Java如何通过反射获取私有构造、私有对象、私有字段、私有方法

 更新时间:2021年12月14日 11:27:10   作者:弦上的梦  
这篇文章主要介绍了Java如何通过反射获取私有构造、私有对象、私有字段、私有方法,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Java反射获取私有构造、私有对象、私有字段、私有方法

1. 创建测试的私有对象

/**
 * @author lirong
 * @desc 测试对象
 * @date 2019/06/20 20:07
 */
public class Person {
    private int age = 5;
    private String name;
    private Person(){}
    private String test(String name){
        System.out.println("name: "+name);
        return "test";
    }
}

2. 获取私有对象中的属性和方法

/**
 * @author lirong
 * @desc 反射获取私有属性和方法
 * @date 2019/06/20 20:10
 */
public class Test {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 1. 获取class对象
        Class clazz = Person.class;
        // 2. 获取私有无参构造
        Constructor c = clazz.getDeclaredConstructor();
        // 3. 设置访问为可见
        c.setAccessible(true);
        // 4. 通过构造器创建实例对象
        Person person = (Person) c.newInstance();
        
        // 根据字段名称获取class中的字段
        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);
        System.out.println(age.getName() + " = " + age.get(person));
        // 修改私有变量的默认值
        age.set(person, 18);
        System.out.println(age.getName() + " = " + age.get(person));
        // 5. 获取所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            // 设置字段的可见性
            f.setAccessible(true);
            String name = f.getName();
            Object o = f.get(person);
            System.out.println(name + " - " + o);
        }
        // 6. 获取所有的方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method m : methods) {
            m.setAccessible(true);
            String name = m.getName();
            Object invoke = m.invoke(person, "张三");
            System.out.println(name + " = "+invoke);
        }
    }
}

通过反射获取私有内部类对象

首先是我们的目标对象:

class Out {
    //目标获取Inner对象
    private class Inner {
        //内部类的私有成员属性
        private String inner = "ccc";
    }
}

直接列出代码

public class Main {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) throws Exception {
        //获取外部类
        Class clzz = Out.class;
        //获取外部类默认无参构造方法
        Constructor con = clzz.getDeclaredConstructor();
        //实例一个外部类对象
        Out outObj = (Out) con.newInstance();
        //获取外部类内的所有内部类
        Class innerClazz[] = clzz.getDeclaredClasses();
        //遍历
        for (Class c : innerClazz) {
            //获取修饰符的整数编码
            int mod = c.getModifiers();
            //返回整数编码对应的修饰符的字符串对象
            String modifier = Modifier.toString(mod);
            //找到被private修饰的内部类
            if (modifier.contains("private")) {
                //根据内部类的特性,需要由外部类来反射获取内部类的构造方法(这里获取的是内部类的默认构造方法)
                Constructor cc = c.getDeclaredConstructor(clzz);
                //由于内部类是私有的,需要强制获取构造方法的访问权限
                cc.setAccessible(true);
                //由外部类对象来反射获取内部类的对象
                Object obj=cc.newInstance(outObj);
                //获取内部类的私有成员属性inner
                Field f=c.getDeclaredField("inner");
                //获取访问权限
                f.setAccessible(true);
                //获取内部类对象obj中的私有成员属性inner的值
                System.out.println(f.get(obj));
            }
        }
    }
}

输出结果:

ccc

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 详解Java中的Lambda表达式

    详解Java中的Lambda表达式

    这篇文章主要介绍了Java中的Lambda表达式的的相关资料,文中讲解非常详细,示例代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-06-06
  • Spring高阶用法之自定义业务对象组件化

    Spring高阶用法之自定义业务对象组件化

    这篇文章主要介绍了Spring高阶用法之自定义业务对象组件化,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-03-03
  • Java数据类型Integer与int的区别详细解析

    Java数据类型Integer与int的区别详细解析

    这篇文章主要介绍了Java数据类型Integer与int的区别详细解析,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null,int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比,需要的朋友可以参考下
    2023-12-12
  • Hibernate环境搭建与配置方法(Hello world配置文件版)

    Hibernate环境搭建与配置方法(Hello world配置文件版)

    这篇文章主要介绍了Hibernate环境搭建与配置方法,这里演示Hello world配置文件版的具体实现步骤与相关代码,需要的朋友可以参考下
    2016-03-03
  • Java并发框架中的AQS详细解析

    Java并发框架中的AQS详细解析

    这篇文章主要介绍了Java并发框架中的AQS详细解析,之前说锁的升级的时候,说到了自旋锁会空转几次尝试等待获取资源,其实这一系列的动作是有一个规范的这个规范叫做同步发生器AbstractQueuedSynchronizer ,简称AQS,需要的朋友可以参考下
    2024-01-01
  • Java中Static关键字的五种用法详解

    Java中Static关键字的五种用法详解

    这篇文章主要介绍了Java中static的五种用法:修饰成员变量,修饰成员方法,修饰内部类,静态代码块,静态导包,想详细了解的小伙伴可以参考阅读本文
    2023-03-03
  • java 线程池如何执行策略又拒绝哪些策略

    java 线程池如何执行策略又拒绝哪些策略

    这篇文章主要介绍了java 线程池如何执行策略又拒绝哪些策略,文章通过线程池的执行方法 execute() 展开全篇内容,需要的小伙伴可以参考一下
    2022-05-05
  • Jvm调优和SpringBoot项目优化的详细教程

    Jvm调优和SpringBoot项目优化的详细教程

    这篇文章主要介绍了Jvm调优和SpringBoot项目优化,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • Java NIO写大文件对比(win7和mac)

    Java NIO写大文件对比(win7和mac)

    这篇文章主要介绍了Java NIO写大文件对比(win7和mac),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-07-07
  • SpringBoot如何读取war包jar包和Resource资源

    SpringBoot如何读取war包jar包和Resource资源

    这篇文章主要介绍了SpringBoot如何读取war包jar包和Resource资源,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01

最新评论