------- android培训、java培训、期待与您交流! ----------
1,什么是反射
java 程序在运行期间可以动态加载、解析和使用在编译期间并不确定的类型,我们称之为反射或内省
2,反射提供的功能
- 动态加载
- 解析类的结构,获取内部信息
- 操作该类型或其实例(访问属性、调用方法、创建实例)
使用反射第一步:获取Class对象
获取class对象主要有以下四种
Person p1 = new Person(); Class c1 = Class.forName("pojo.Person"); Class c2 = p1.getClass() Class c3 = pojo.Person.class Class c4 = Integer.TYPE
第四种方式需要注意一下,只适用于JAVA的内置封装类型,还有Integer.TYPE与Integer.class 是不一样的,Integer.TYPE与int.class是一样的,也就是说java中8种内置类型的.class(int.class,char.class,byte.class等)分别是对应他们的封装类的TYPE属性(Integer.TYPE),而并非.class,这点不要弄混了。
使用反射第二步:获取类的属性
public Field[]getDeclaredFields():返回当前类的所有属性,无论访问控制权限,不包括父类
public FieldgetDeclareField(String name):返回当前类的特定属性
public Field[]getFields():返回当前类和父类层次的public属性
public Field getField(String name):返回当前类或者父类层次public 的特性属性
<pre name="code" class="java">Field[] fs = c.getDeclaredFields(); for(Field f: fs) { <span style="white-space:pre"> </span>System.out.println("----------"); <span style="white-space:pre"> </span>System.out.println("属性:"+f.toString()); <span style="white-space:pre"> </span>System.out.println("属性类型:"+f.getType()); <span style="white-space:pre"> </span>System.out.println("属性名称:"+f.getName()); <span style="white-space:pre"> </span>int mod = f.getModifiers(); <span style="white-space:pre"> </span>System.out.println("属性修饰符:"+Modifier.toString(mod)); }
使用反射第三步:获取类的方法
public Method[]getDeclaredMethods():返回当前类的所有方法(非构造),无论访问控制权限,不包括父类
public MethodgetDeclareMethod(String name,Class<?> parameterTypes): 返回当前类的特定方法
public Method[]getMethods():返回当前类和父类层次的public方法
public Method getMethod(String name,Class<?>parameterTypes):返回当前类或者父类层次public 的特性方法
Method[] ms = c.getDeclaredMethods(); for(Method m : ms) { <span style="white-space:pre"> </span>System.out.println("---------------------------"); <span style="white-space:pre"> </span>System.out.println("方法:"+m.toString()); System.out.println("\t方法名:"+m.getName()); int mod = m.getModifiers(); System.out.println("\t方法修饰符:"+Modifier.toString(mod)); }
使用反射第四步:创建类实例(调用构造方法)
public Constructor[]getDeclaredConstructors():返回当前类的所有构造方法,无论访问控制权限,不包括父类
public ConstructorgetDeclareConstructor(String name,Class<?> parameterTypes):返回当前类的特定方法
public Constructor[]getConstructors():返回当前类和父类层次的public构造方法
public Constructor getConstructor(Stringname,Class<?> parameterTypes):返回当前类或者父类层次public 的构造方法
这里是使用Constructor类来创建实例对象,如果这个类有自己的空参构造方法的话,还有一种更简单的创建实例的方法,这个方法被广泛的引用在各大框架中Class c = Class.forName("pojo.Person"); Class[] argsType = {String.class,int.class}; // 调用有参构造方法 Constructor constructor = c.getConstructor(argsType); Object obj = constructor.newInstance("小明",24); System.out.println(obj);
Class c = Class.forName("pojo.Person"); Object obj = c.newInstance();
直接调用类对象的newInstance()方法,这也就是在使用Hibernate、IBatis等框架的时候pojo必须有自己的空参构造的原因,在底层他们就是调用这个方法来创建对象的。
使用反射第五步:调用类的方法
前面讲到了如何获取类的方法,但是又该如何调用类的方法呢?用以下代码实现
<pre name="code" class="java">Person obj = new Person(); Class c = obj.getClass(); Method method = c.getMethod(methodName, String.class); method.invoke(obj,value);