标签:动态获取 注意 运行 静态 ceo 实现 设计 好用 目标
java的类型信息在运行时如何表示?通过Class对象,class类是程序运行期间,为所有的对象维护一个运行时的类型标识,保存这些信息的类被称为class。
如何获取类的class对象引用?
1. Class.forName();forname是class类的静态方法。
2. 如果已经有一个对象,可以调用对象的getClass(),此方法属于根类object。
3. 使用类字面常量.class;不仅可以用于普通的类,还可以用于接口,数组,以及基本数据类型。
注意,一个class对象表示一个类型,未必一定是一种类。如Class c = int.class,c不是类,但是一个class类型对象。
.class和forName()的区别:
程序中每一个类都有一个class对象,所有的类都是在对其第一次使用时,动态加载到JVM中。当程序创建第一个对类的静态成员的引用时(构造器也是类的静态方法),就会加载这个类,然后进行类的静态初始化。通过.class得到class对象引用,不会触发类的初始化,而使用forName()会使类进行初始化。
Class类是泛型的。我们可以用泛型语法,让编译器进行额外的类型检查。
如 Class<?> intClass = int.class; Class<House> houseType = House.class;
我们可以根据得到的class引用,判断一个对象obj是不是某个Class类型的实例(如类名为Base)。
1. obj instanceof Base
2. Base.class.isInstance(obj)
instanceof 和insInstance都保持了类型的概念,即可以识别出继承的关系。
若我们想要在运行时获取类的信息呢?在编译时不能确定需要的是哪个类,所以.class和getClass()是显然不好用的。
Java反射机制主要提供了以下功能: 在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。
Class类与java.lang.reflect类库一起对反射的概念进行了支持。
在Class类中:
Static Class forName(String className)可以得到该类型的对象引用
Object newInstance()创建该类型实例
默认使用类的无参数构造器,如果创建有参数实例,需要先调用getConstructors(),得到一个Constructor构造器的实例。
Eg.e.getClass().newInstance() e.getConstructor(String.class).newInstance(“233”)
Field[] getFields()
Method[] getMethods()
Constructor[] getConstructors()
java.lang.reflect类库中有三个类:
Field:描述类的域
Method:描述类的方法
Constructor:描述类的构造器
在method类中:
Public Object invoke(Object implicitPara,Object[] explicitPara) 调用任意方法。
通过这些类库中类的方法可以实现动态获取类型信息。
代理是基本的设计模式之一,代理通常充当着中间人的身份。一个对象不想或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
静态代理:写在代码里,通过中间类去操作实际类,也就是被代理的类
动态代理:动态地创建代理,动态地实现对实际类的调用。
反射和java.lang.reflect.Proxy等相关类实现了动态代理。
动态代理分为3个步骤:
1. 建立委托类,即被代理的类,创建Interface接口和实现类;
2. 创建实现了InvocationHandler接口的代理类,在invoke()内执行代理操作;
3. 创建代理对象,将代理对象传递给调用者。
通过调用proxy的静态方法newProxyInstance()创建动态代理,
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
这个方法需要三个参数:
1. ClassLoader loader指明生成代理对象使用的类装载器
2. Class<?>[] interfaces指定代理器实现的接口列表
3. InvocationHandler h指明Invocation接口的一个实现,就是定义的代理类要做的事情。
通过动态代理,不管调用代理对象的什么方法,都是调用代理器的invoke方法,在这里人为地决定了如何调用被代理对象的原始方法,如何进行额外的处理。相当于对被代理对象直接方法调用的拦截。
标签:动态获取 注意 运行 静态 ceo 实现 设计 好用 目标
原文地址:http://blog.51cto.com/13580976/2066008