java反射机制
1.认识反射
反射,从这个反字可以看出与我们平时正常的使用逻辑肯定不一样,那么到底什么地方不一样了?想要了解“反”,就得先了解一下正的概念。
在正常情况下,如果要使用一个类,必须要经过以下几个步骤:
(1)使用important导入类所在的包(类:java.lang.Class)
(2)通过关键字new进行类对象实例化(构造方法:java.lang.reflect.Constructor)
(3)产生对象可以使用“对象.属性”进行类中属性的调用(属性:java.lang.reflect.Field)
(4)通过“对象.方法()”调用类中的方法(方法:java.lang.reflect.Method)
括号中的红色字体是每个步骤对应反射中使用到的类,如果现在不了解,可以先不用管,后面会一一介绍,这里是为了方便进行比较。
在反射中,使用一个类并不需要导入类的所在包,只要知道类的完整路径就可以知道该类中的所有信息。
反射不需要有明确的类型对象,所有的对象都使用Object表示。可以直接用Object的与反射机制的混合调用类中的方法
什么是反射机制?
简单说,反射机制值得是程序在运行时能够获取自身的信息。在java中,只要给定类的名字,那么就可以通过反射机制来获得类的所有信息。
优缺点
反射的优点当然是体现在它的动态性上面,能运行时确定类型,绑定对象。动态编译最大限度发挥了java的灵活性,体现了多态的应用,降低类之间的藕合性。 一句话,反射机制的优点就是可以实现动态创建对象和编译,特别是在J2EE的开发中,它的灵活性就表现的十分明显。比如,一个大型的软件,不可能一次就把 它设计的很完美,当这个程序编译后,发布了,当发现需要更新某些功能时,我们不可能要用户把以前的卸载,再重新安装新的版本,假如这样的话,这个软件肯定是没有多少人用的。采用静态的话,需要把整个程序重新编译一次才可以实现功能的更新,而采用反射机制的话,它就可以不用卸载,只需要在运行时才动态的创建 和编译,就可以实现该功能。
它的缺点是对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于只直接执行相同的操作。
常用方法
①. 判断对象是否属于反射得到的类(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);
}
}
}
②. 获取某个反射类的所有属性字段
/**
* 获取反射类的所有属性字段
*
* @param ownerClass 反射的类
* @return
* @throws Exception
*/
public Field[]getProperty(Class ownerClass) throws Exception {
//获取该类所有属性字段
//Field[] fields = ownerClass.getFields();//只获取public访问权限的属性字段(包括父类的)
Field[] fields =ownerClass.getDeclaredFields();//只获取该类的所有访问权限的属性(不含父类)
//输出所有属性字段
for(int i=0;i System.out.println("属性:"+fields[i]); } return fields; } ③. 获取反射类的某个public属性值 /** * 获取反射类的某个public属性值 * * @param ownerClass 反射的类 * @param fieldName 属性名 * @return * @throws Exception */ public ObjectgetProperty(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; }