一、反射的理解
反射类似于我们平时见到的平面镜的反射:被反射的目标(任意一个已知名称的类),反射出来的“镜像”(我们的类对象<Java中任意一个类都对应有一个类对象>),通过这个“镜像”,类对象,我们就可以在运行时获取任意一个已知名称的类对应的信息。
二、Java反射机制提供的功能
Java反射机制主要提供了以下功能:在运行时判断任意一个独享所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;在运行时创建新类对象,生成动态代理。
Java的反射机制容许程序在运行时加载、探知、使用编译期间完全未知的classes.
1、获取class对象
a.使用Class类的静态方法。例如:Class.forName("java.lang.String");
b.使用类的.class语法。例如:String.class;
c.使用对象的getClass()方法,如:
String str = "aa"; Class<?> classType = str.getClass();
getClass()方法定义在Object类中,不是静态方法,需要通过对象来调用,并且它声明为final,表明不能被子类所覆写。
2、获取类的Fields
java.lang.reflect.Field[]fields=a.getClass().getFields();
比如eclipse,写出一个对象名,一按点,就会自动弹出该对象的所有方法,这就用了java的反射原理得到了类的属性和方法。
3、获取类的Method
importjava.lang.reflect.Method; publicclass DumpMethods { public static void main(String[] args)throws Exception { //获得字符串所标识的类的class对象 Class<?> classType =Class.forName("java.lang.String");//在此处传入字符串指定类名,所以参数获取可以是一个运行期的行为,可以用args[0] //返回class对象所对应的类或接口中,所声明的所有方法的数组(包括私有方法) Method[] methods =classType.getDeclaredMethods(); //遍历输出所有方法声明 for(Method method : methods) { System.out.println(method); } } }
4、获取类的constructor
//使用有构造函数实例化bean Constructorconstructor = clazz.getConstructor(new Class[]{String.class,String[].class}); sb = (SimpleBean) constructor.newInstance(newObject[]{"刘腾腾",newString[]{"football","basketball"}}); System.out.println(sb);
5、新建类的实例
Class<?>classType = ExtendType.class; Object inst =classType.newInstance(); System.out.println(inst);
6、调用类的函数
Class<?>classType = ExtendType.class; Object inst =classType.newInstance(); Method logMethod =classType.getDeclaredMethod("Log", String.class); logMethod.invoke(inst,"test");
7、设置/获取类的属性值
Class<?>classType = ExtendType.class; Object inst =classType.newInstance(); Field intField =classType.getField("pubIntExtendField"); intField.setInt(inst,100); int value = intField.getInt(inst);
三、优缺点
优点:可以实现动态创建对象和编译即运行时确定类型,绑定对象。
缺点:对性能有影响。使用反射基本上是一种解释操作,我们可以告诉JVM,我们希望做什么并且它满足我们的要求。这类操作总是慢于直接执行相同的操作。
四、总结
假如A,B都在开发类,若A要使用B写的类,但是B没有完成,那么A的代码是不能通过编译的。此时利用java反射机制,就可以让A在没有B所写的类的时候来完成自身代码的编译。
反射提供了运行时加载类,动态获取类的名称、方法、属性、修饰符等等。程序之间解耦,灵活性很大,代码的可读性好。