Java中反射的概念

反射

反射的概念

Java反射机制实在运行状态中,对于任何一个类,都能知道这个类的所有属性和方法。对于任意一个对象,都能调用它的任意方法和属性。

这种动态获取信息以及动态调用对象方法的功能被称为Java反射机制。

获取字节码对象的三种方式
//1.使用类名调用.class属性(.class不是只有类能调用)
Class c1 = String.class;

//2.使用一个类的对象调用.getClass()方法
Class c2 = "abd".getClass();

//3.使用Class类的静态方法forName("类全名")
Class c3 = Class.forName("java.lang.String");

System.out.println(c1 == c2);//true
System.out.println(c2 == c3);//true
反射操作构造方法

反射获取构造方法:

  • getConstructor(Class… c) 可以获取某一个构造方法(公共的)
  • getConstructors() 可以获取所有的构造方法(公共的)

反射执行构造方法

  • newInstance(Object… obj) : 执行当前构造方法创建对象。(方法传递的参数是创建对象时的实际参数)
Class c1 = Class.forName("com.test.reflect.Student");

        // 获取空参构造
        Constructor con1 = c1.getConstructor();
        // 获取有参构造
        Constructor con2 = c1.getConstructor(String.class, int.class);

        // 使用无参构造创建对象
        Object o1 = con1.newInstance();
        System.out.println(o1);
        
        // 使用有参构造创建对象
        Object o2 = con2.newInstance("张三", 21);
        System.out.println(o2);
反射操作成员方法

反射获取成员方法

  • getMethod(String name, Class… c) :获取一个成员方法(公共的)

String name 表示方法名称
Class… c 表示的是方法的参数的类型

反射执行成员方法

  • Object invoke(Object obj , Object… o) :让方法执行
    第一个参数表示执行的对象
    第二个参数表示方法的实际参数
    返回值表示方法的实际返回值
 Class c1 = Class.forName("com.test.reflect.Student");

        // 获取空参构造
        Constructor con = c1.getConstructor();
        // 通过构造方法创建对象
        Object o = con.newInstance();

        // 设置姓名方法
        Method method1 = c1.getMethod("setName", String.class);
        method1.invoke(o, "张三");
        // 获取姓名方法
        Method method2 = c1.getMethod("getName");
        System.out.println(method2.invoke(o));// 输出张三
暴力反射

暴力反射的概念:
反射正常情况下遵从java权限修饰的规则。
​如果使用暴力反射就可以打破权限修饰符的规则。
​写法: 在所有的获取方法之间加declared词就可以了,然后调用setAccessable(true)就表示可以访问了。

// 通过暴力反射获取变量
private String name;
private int age;

// 私有化一个方法进行测试
private String getName() {
    return name;
}
Class c1 = Class.forName("com.test.reflect.Student");

// 获取空参构造
Constructor con = c1.getConstructor();
// 通过构造方法创建对象
Object o = con.newInstance();

// 设置姓名方法
Method method1 = c1.getMethod("setName", String.class);
method1.invoke(o, "张三");

// 暴力反射获取被私有的方法
Method method2 = c1.getDeclaredMethod("getName");
// 设置为可以访问
method2.setAccessible(true);
System.out.println(method2.invoke(o));

// 暴力反射获取被私有的成员
Field name = c1.getDeclaredField("name");
System.out.println(name);
反射的应用场景

一般反射都是配合配置文件使用,这样我们修改一些参数的时候直接修改配置文件就可以了。

className=com.test.reflect.Student
methodName=getName
//Properties配置文件
Properties prop = new Properties();
//读取文件的键值对
prop.load(new FileReader("practice\\a.properties"));

//根据键获取值
String className = prop.getProperty("className");
String methodName = prop.getProperty("methodName");

Class c = Class.forName(className);
//字节码获取构造方法
Constructor con = c.getConstructor();
//创建对象
Object o = con.newInstance();
Method method1 = c.getMethod("setName", String.class);
method1.invoke(o, "张三");

//获取方法
Method m = c.getMethod(methodName);
//执行方法
System.out.println(m.invoke(o));
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鹈鹕吃吃吃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值