反射

100 阅读2分钟

反射简而言之就是可以动态获取类和对象信息。
反射机制:运行时分析类的能力;运行时检查对象;实现泛型数组操作代码;利用Method对象。
反射的应用:1.支持用户界面生成器;2.对象关系映射器;3.动态查询类能力。
JAVA对象类型:1.编译时类型,即在声明对象时所采用的类型;2.运行时类型,即为对象赋值时所采用的类型。
编译时,编译器必须知道所有要通过运行时类型信息(RTTI)来处理的类。(不包括对象的引用、磁盘文件、网络连接中获取的字节等,因为他们在编译器生成代码很久之后才出现)。运行时,反射可以打开和检查.class文件,获取相应信息。

利用反射分析类

1.Class类
①getClass():返回一个Class类型的实例;
②.getName():返回类的名字;
③forName():可获得类名对应的Class对象(静态类方法)

Employee e;
Class cl = e.getClass();
Class c2 = Employee.class;
String name = cl.getName();//Employee

//使用静态类方法forName可获得类名对应的Class对象
String className = "java.util.Random";//类的包路径及名称
Class cl = Class.forName(className);
//若是类名或接口名正常执行,若不是抛出检查型异常,需要提供一个异常处理器

S:包含main方法的类被加载,加载所有需要的类,这些类又需要加载他们需要的类
T:大型应用加载慢,用户不耐烦
A:1.保证包含main方法的类没有显式地引用其他类;2.显示一个启动画面;
3.通过调用Class.forName强制加载其他类。
R:制造假象

1.Field类-公共字段

getField()//包括父类的公共成员
getDeclareField()//不包含父类成员

2.Method类-方法

//调用包装在当前Method对象中的方法,第一个是隐式参数,其余对象提供了显示参数
//可实现动态代理
Object invoke(Object obj, Object... args)

3.Constructor类-构造器

Constructor[] constructor = clazz.getDeclaredConstructors();
for(Constructor c:constructor) {
    System.out.println(c.toString());
}

利用反射构建对象

1.newInstance方法创建实例,要求对应类有默认的空构造器

Class clazz = Class.forName("hello.java.reflect.Persion");
Person p = (Person) clazz.newInstance;

2.先用class方法获取指定的Constructor方法,再通过该构造方法创建实例

Constructor c = clazz.getDeclaredConstructor(String.class);
Person p1 = (Person) c.newInstance("王二");

利用反射动态调用方法

主要利用Method的invoke方法,具体方法如下:

Class clz = Class.forName("hello.java.reflect.Persion");
Method method = clz.getMethod("setName",String.class);
Constructor constructor = clz.getConstructor();
Object object = constructor.newInstance();
method.invoke(object,"alex");

使用反射在运行时分析对象

setAccessible(boolean flag);
boolean trySetAccessible();//设置可访问标志,拒绝访问则返回false
boolean isAccessible();//是否可访问
static void setAccessible(AccessibleObject[] array, boolean flag)

//java.lang.reflect.Field
Object get(Object obj)
void set(Object obj,Object newValue)

基于构建的编程

组装不同组件、设置构件属性值创建程序,要求构件可实例化并且暴露部分信息允许程序员读取和修改构件的属性。