反射
动态语言
程序运行时,可以改变程序结构或变量类型。典型的有Python、ruby、javascript等,如:
1 2 3 4 function test ( ) { var s = "var a=3;var b=5;alert(a+b);" eval (s); }
C,C++,Java不是动态语言,但JAVA有一定的动态性,可以利用反射机制、字节码操作获得类似动态语言的特性。
反射机制
指的是可以在运行时加载、探知、使用编译期间完全未知的类。
程序在运行状态中,可以动态加载一个只有名称的类,对于任意一个已加载的类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能调用它的任意一个方法和属性;
加载完类之后,在堆内存中,就产生了一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。我们可以通过这个对象看到类的结构。这个对象就像一面镜子,透过这个镜子看到类的结构,所以被形象的称为反射(reflection)
Class类介绍
java.lang.Class类十分特殊,用来表示java中类型本身
Class类的对象包含了某个被加载类的结构。一个被加载的类对应一个Class对象。
当一个class被加载,或当加载器(class loader)的defineClass()被Jvm调用时,JVM便自动产生Class对象
Class类是Reflection的根源,针对任何想动态加载、运行的类,唯有先获得相应的Class对象
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 System.out.println(c.getName()); System.out.println(c.getSimpleName()); Field[] field = c.getFields(); Field[] fields = c.getDeclaredFields(); Field f= c.getField("name" ); Method[] method = c.getMethods(); Method[] methods = c.getDeclaredMethods(); Method me = c.getMethod("getName" ,null ); Method m = c.getMethod("setName()" ,String.class); Constructor[] constructor = c.getConstructors(); Constructor[] constructors = c.getDeclaredConstructors(); Constructor co = c.getConstructor(null ); Constructor cos = c.getDeclaredConstructor(String.class,int .class);
动态操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 String str = (String) c.newInstance(); System.out.println(str); Constructor co = c.getConstructor(String.class); String s = (String) co.newInstance("hello" ); System.out.println(s); String s2 = (String) c.newInstance(); Method m = c.getMethod("length" ,null ); System.out.println(m.invoke(s2)); Field f = c.getDeclaredField("hash" ); f.setAccessible(true ); f.set(s2,12345 ); System.out.println(s2.hashCode());