Java 反射机制

本文介绍Java反射机制的基本概念及其应用场景,包括如何通过不同方式获取Class对象、构造方法、成员方法及成员变量等,并讨论反射机制对单例模式的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

java语言的反射机制是指能够动态获取信息以及动态调用对象的方法的功能。

一个类中包含成员变量、方法、构造方法、包等等信息,反射机制将class文件读入内存,并为之创建一个Class对象。

一句话,反射是框架设计的灵魂。

反射的使用

获取Class信息

//第一种获取Class对象方式
Designer designer = new Designer("A001","Alex","Designer", 30);
Class designerClass1 = designer.getClass();
System.out.println(designerClass1.getName());

//第二种获取Class对象方式
Class designerClass2 = Designer.class;
System.out.println(designerClass2.getName());

//第三种获取Class对象方式
try {
      Class designerClass3 = Class.forName("com.maowei.learning.reflection.pojo.Designer");
      System.out.println(designerClass3.getName());
}catch (ClassNotFoundException e){
      e.printStackTrace();
}

上述代码列出了获取Class对象的三种方式,第一种方式多此一举,使用反射的目的就是动态创建对象,既然对象已经有了,还要反射作甚;第二种,需要导入类的包,依赖太强,不导包就抛编译错误;一般使用第三种,只需要一个代表包路径的字符串即可。

获取构造方法

Class designerClass3 = Class.forName("com.maowei.learning.reflection.pojo.Designer");
//System.out.println(designerClass3.getName());

Constructor[] conArr = designerClass3.getConstructors();
for(Constructor c : conArr)
    System.out.println(c);

System.out.println("===============这是分割线===============");

conArr = designerClass3.getDeclaredConstructors();
for(Constructor c : conArr)
    System.out.println(c);

System.out.println("===============这是分割线===============");

Constructor constructor = designerClass3.getConstructor(String.class,String.class,String.class, int.class);
System.out.println(constructor);

System.out.println("===============这是分割线===============");

constructor = designerClass3.getDeclaredConstructor();
System.out.println(constructor);

上述代码列出了两种获取构造方法:

  • 批量的方法:
    public Constructor[] getConstructors():所有”公有的”构造方法
    public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)

  • 获取单个的方法:
    public Constructor getConstructor(Class… parameterTypes):获取单个的”公有的”构造方法:
    public Constructor getDeclaredConstructor(Class… parameterTypes):获取”某个构造方法”可以是私有的,或受保护、默认、公有;

有了构造方法之后便可调用newInstance方法创建对象,

Constructor constructor = designerClass3.getConstructor(String.class,String.class,String.class, int.class);
Object obj1 = constructor.newInstance("A001","Alex","Designer", 30);

constructor = designerClass3.getDeclaredConstructor();
con.setAccessible(true);//暴力访问(忽略掉访问修饰符)
Object obj2 = constructor.newInstance();

获取成员方法

Constructor constructor = designerClass3.getConstructor(String.class,String.class,String.class, int.class);
Object obj1 = constructor.newInstance("A001","Alex","Designer", 30);

Method[] methods = designerClass3.getMethods();
for(Method m : methods){
    System.out.println(m);
}

System.out.println("===============这是分割线===============");

methods = designerClass3.getDeclaredMethods();
for(Method m : methods){
    System.out.println(m);
}

跟构造方法一样,上述代码也列出了两种获取成员方法:

  • 批量的方法:
    public Method[] getMethods():所有”公有的”构造方法
    public Method[] getDeclaredMethods():获取所有的构造方法(包括私有、受保护、默认、公有)

  • 获取单个的方法:
    public Method getMethod(String name, Class< ? >… parameterTypes):获取单个的”公有的”构造方法:
    public Method getDeclaredMethod(String name, Class< ? >… parameterTypes):获取”某个构造方法”可以是私有的,或受保护、默认、公有;

获取Method对象之后可以调用invoke方法实现对成员方法的访问

Method method = designerClass3.getMethod("doWorking");
method.invoke(obj1);

System.out.println("===============这是分割线===============");

method = designerClass3.getDeclaredMethod("working02");
method.setAccessible(true);
method.invoke(obj1);

获取成员变量

Field[] fields = designerClass3.getFields();
for(Field f : fields){
    System.out.println(f);
}

System.out.println("===============这是分割线===============");

fields = designerClass3.getDeclaredFields();
for(Field f : fields){
    System.out.println(f);
}

此处 getFields() 方法和 getDeclaredFields() 方法的区别相信大家已经知道了,就是权限修饰符的不同。

当获取了Field对象之后,我们可以进行修改操作,

Field f = designerClass3.getField("age");
f.set(obj1, 31);

System.out.println("===============这是分割线===============");

f = designerClass3.getDeclaredField("id");
f.setAccessible(true);
f.set(obj1,"A002");

反射模式对单例模式的破坏

由于权限控制是程序编译期的处理机制,而反射处理发生在程序的运行期,上述代码也证明了可以通过反射的方式访问对象的私有构造方法,这便会对单例模式造成破坏,因此在使用时格外注意。

总结

本文大体介绍了反射机制的一些用法,完整的反射机制肯定复杂很多,正如开篇提到的“反射是框架设计的灵魂”,只有熟练理解了反射机制,才能写出高质量的框架代码。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值