Java反射机制
Java反射机制
- 什么是反射?
- 反射机制能做什么?
- 获取字节码对象的三种方式
- 简单实用例子
- 创建对象实例
- 获取构造器创建对象实例
- 获得成员变量
- 获取对象中的方法
- 反射的实际使用场景
什么是反射?
- 反射机制是在运行状态中,对于任意一个类,都能知道这个类的所有属性和方法,对于任意一个对象,都能调用它的任意一个方法和属性,这种动态获取的信息以及动态调用对象的方法的功能就称为java语言的反射机制。
- 想要使用反射机制就必须获得该类的字节码对象(.class)。
反射机制能做什么?
- 在运行时判断一个对象所属的类
- 在运行时判断任意一个类所具有的成员变量和方法
- 在运行时构造任意一个类的对象
- 在运行时调用任意一个对象的方法
- 生成动态代理
获取字节码对象的三种方式
通过实例对象的getClass()方法获取
Persion p = new Persion();
Class class = p.getClass();
….通过类的静态属性获取
Class class = Persion.class;
通过全限定名直接获取到一个类的
字节码文件对象
,此时还是源文件阶段,还没有变成字节码文件。Class class = Class.forName(“com.demo.Persion”);
开发中最常用的是方式3,它只需要提供全限定名即可创建对象,通常可以配置在配置文件中,更加方便扩展性强。
简单实用例子
创建对象实例
public class Persion{
String name;
//省略get/set
}
@Test
public void test(){
Class class = Class.forName("com.demo.Persion");
Object obj = class.newInstance();
}
获取构造器创建对象实例
public class Persion{
String name;
//省略get/set
public Persion(String name) {
this.name = name;
}
}
@Test
public void test(){
Class class = Class.forName("com.demo.Persion");
Constructor constructor = class.getConstructor(String.class);
Persion persion = (Persion)constructor.newInstance("tom");
//获取所有构造方法
Constructor[] constructor = persion.getConstructors();
for (Constructor cons : constructor) {
//获得构造函数中的所有参数类型的字节码对象
Class[] parameterTypes = cons.getParameterTypes();
}
}
获得成员变量
public class Persion{
String name;
public String addr;
//省略get/set
}
@Test
public void test(){
Class persion = Class.forName("com.demo.Persion");
Object obj = persion.newInstance();
//获得指定成员变量,如果是public修饰的可以使用getFile()获取
Field file = persion.getDeclareField("name");
//如果是私有属性,需要打开可见权限
file.setAccessible(true);
//设置指定对象的成员变量值
file.set(obj,"tom");
//获得所有成员变量
Filed[] fileds = persion.getDeclareFields();
for(Filed res : fileds) {
res.setAccessible(true);
}
}
获取对象中的方法
public class Persion{
//省略属性和get/set
public void print(String message){
System.out.print("print " + message);
}
}
@Test
public void test() {
String name = "com.demo.Persion";
Class serviceClass = Class.forName(name);
Object obj = serviceClass.newInstance();
//获得指定名称方法,如果有参数填上参数类型的Class类型
Method print = serviceClass.getDeclareMethod("print",String.class);
//私有方法如需要打开可见权限
print.setAccessible(true);
//指定某个对象调用方法,有参数就加上参数
print.invoke(obj,"hahaha");
//获得所有方法
Method print = serviceClass.getDeclareMethods();
for (Method method : methods) {
method.setAccessible(true);
//获得方法的参数
Class<?>[] parameterTypes = method.getParameterTypes();
}
}
反射的实际使用场景
- Spring中的IOC控制反转。容器通过配置文件生产和DI都是依赖反射来实现的。传送门SpringIOC和DI
- 动态代理。Java的动态代理中生成代理对象就是通过反射获取接口和获取指定实现类创建实例。
- 编辑器的代码提示也是通过反射获取到类中的方法和属性
还没有评论,来说两句吧...