1. Java的反射机制
动态语言是指在程序运行时允许改变程序结构或者变量类型,从这个观点看,JAVA和C++一样,都不是动态语言。但Java它却有着一个非常突出的动态相关机制:反射。
Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
Java反射机制主要提供了以下功能:
(1)在运行时判断任意一个对象所属的类;
(2)在运行时构造任意一个类的对象;
(这一条在下面没有展示实例,但在之前写过的一篇Java中创建对象的5种方式中有所介绍,有兴趣的可以参考查看。)
(3)在运行时判断任意一个类所具有的成员变量和方法;
(4)在运行时调用任意一个对象的方法;
(5)生成动态代理。
2. Java反射API
反射API用来生成在当前Java虚拟机中的类、接口或者对象的信息。
Class类:反射的核心类,可以获取类的属性,方法等内容信息。
Field类:Java.lang.reflect.表示类的属性,可以获取和设置类的中属性值。
Method类:Java.lang.reflect。表示类的方法,它可以用来获取类中方法的信息或者执行方法
Construcor类:Java.lang.reflect。表示类的构造方法。
3.反射常见用法
3.1 判断对象是否属于反射得到的类(isInstance)
-
class S {
-
}
-
public class IsInstance {
-
public static void main(String args[]) {
-
try {
-
Class cls = Class.forName("S");
-
boolean b1 = cls.isInstance(new Integer(37));
-
System.out.println(b1);
-
boolean b2 = cls.isInstance(new S());
-
System.out.println(b2);
-
}
-
catch (Throwable e) {
-
System.err.println(e);
-
}
-
}
-
}
3.2 获取某个反射类的所有属性字段
-
-
-
-
-
-
-
-
public Field[] getProperty(Class ownerClass) throws Exception {
-
-
-
-
Field[] fields = ownerClass.getDeclaredFields();
-
-
-
for(int i=0;i<fields.length;i++){
-
System.out.println("属性:"+fields[i]);
-
}
-
-
return fields;
-
}
3.3 获取反射类的某个public属性值
-
-
-
-
-
-
-
-
-
public Object getProperty(Object owner,String fieldName) throws Exception {
-
-
-
Class ownerClass = owner.getClass();
-
-
-
Field field = ownerClass.getField(fieldName);
-
-
-
Object property = field.get(owner);
-
-
-
System.out.println(fieldName+"的属性值:"+property.toString());
-
-
return property;
-
-
}
3.4 获取反射类的该中的所有方法
-
-
-
-
-
-
-
public Method[] getMethods(Class ownerClass) throws Exception {
-
-
-
-
Method[] methods = ownerClass.getDeclaredMethods();
-
-
-
for(int i=0;i<methods.length;i++){
-
System.out.println("方法:" +methods[i]);
-
}
-
-
return methods;
-
}
3.5 执行反射类的该中的某个方法
-
-
-
-
-
-
-
-
public Object invokeMethod(Object owner,String methodName,Object[] args) throws Exception {
-
-
-
Class ownerClass = owner.getClass();
-
-
-
Method method = ownerClass.getMethod(methodName, null);
-
-
-
Object result = method.invoke(owner, args);
-
-
-
System.out.println("结果返回值:"+ result);
-
-
return result;
-
}
实例演示方法:
-
-
-
-
public void refTest(){
-
String className = "com.java.reflecttest.Student";
-
-
try {
-
-
-
Class<?> stu = Class.forName(className);
-
Object objStu = stu.newInstance();
-
-
-
-
System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-
System.out.println("调用 getProperty 方法,获取Student类的所有属性");
-
getProperty(stu);
-
-
-
-
System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-
System.out.println("调用 getProperty 方法,获取Student类的NAME属性值");
-
getProperty(objStu,"NAME");
-
-
-
-
System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-
System.out.println("调用 getMethods 方法,获取Student类的所有方法");
-
getMethods(stu);
-
-
-
System.out.println("\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n");
-
System.out.println("调用 invokeMethod 方法,执行Student类的getInfo方法");
-
invokeMethod(objStu, "getInfo", null);
-
-
-
} catch (Exception e) {
-
e.printStackTrace();
-
}
-
}
演示所用的Student类:
运行结果:
4. 反射的效率
在Stackoverflow上认为反射比较慢的程序员主要有如下看法,如果你面试遇到了,可以这样回答:
(1)验证等防御代码过于繁琐,这一步本来在link阶段,现在却在计算时进行验证。
(2)产生很多临时对象,造成GC与计算时间消耗。
(3)由于缺少上下文,丢失了很多运行时的优化,比如JIT(它可以看作JVM的重要评测标准之一)
当然,我个人的看法是,现代JVM也不是非常慢了,它能够对反射代码进行缓存以及通过方法计数器同样实现JIT优化,所以反射不一定慢。更重要的是,很多情况下,你自己的代码才是限制程序的瓶颈。因此,在开发效率远大于运行效率的的基础上,大胆使用反射,放心开发吧。
文章转自:http://blog.csdn.NET/xiaoxian8023/article/details/9206055
http://www.jianshu.com/p/f83556bcae59