本文共 5054 字,大约阅读时间需要 16 分钟。
java反射
一、理论
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
二、案例演示
/** * 演示类 */ public static class Person { static { System.out.println("静态代码块执行"); } private Integer id; private String name; public Person(Integer id, String name) { super(); this.id = id; this.name = name; } public Person() { super(); } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [id=" + id + ", name=" + name + "]"; } }
1、获取class对象的三个方式
/** * 类.class * 对象.getClass * Class.forName */ @Test public void test1() throws Exception { String className = "d18_reflect.review.ReflectDemo.Person"; Class clazz = Class.forName(className); // 方式1 clazz = Person.class; // 方式2 clazz = new Person().getClass(); // 方式3 }
2、class.forName() 三个参数以及自设类加载器候补顺序
* 自设定类加载器数组的顺序一般是:自设,Thread,本类,system。 * forName第二个参数如果为false,那么静态代码块不执行。 */ @Test public void test2() throws Exception { String className = "d18_reflect.review.ReflectDemo$Person"; ClassLoader cl = new ClassLoader[]{Thread.currentThread().getContextClassLoader(), getClass().getClassLoader(), ClassLoader.getSystemClassLoader()}[1]; Class clazz = Class.forName(className, true, cl); // 为false,静态代码块不执行 }
3、Method的反射
* getDeclaredMethods : 本类的所有方法 * getMethods:本类的公开方法含父类 */ @Test public void test3() throws Exception { Class clazz = Person.class; Person person = (Person)clazz.newInstance(); Method[] methods = clazz.getDeclaredMethods(); // 所有本类声明的方法 for (Method method : methods) { System.out.println(method); } System.out.println("_______________"); Method[] methods2 = clazz.getMethods(); //本类所有公开的方法 for (Method method : methods2) { System.out.println(method); } Method method = clazz.getMethod("setName",new Class[]{String.class}); System.out.println(method); Object object = method.invoke(person, "哈哈"); //方法执行 }
4、Field的反射
* getDeclaredFields : 本类的声明字段 * getFields:全部公开字段 * setAccessible(true) 可访问公开字段 */ @Test public void test4() throws Exception{ Person demo = new Person(); Class clazz1 = Person.class; Field[] fields = clazz1.getFields(); for (Field field : fields) { System.out.println("全部公开字段"+field.getName()); } Field[] fields2 = clazz1.getDeclaredFields(); for (Field field : fields2) { System.out.println("本类声明字段:"+field.getName()); } //测试如何调用一个字段? Field declaredField = clazz1.getDeclaredField("name"); declaredField.setAccessible(true); //暴力反射,私有字段采用 declaredField.set(demo,"5"); Object object = declaredField.get(demo); System.out.println(object.toString()); }
5、数组的反射
/** * 5、数组的反射 * clazz.isArray() : 判断是数组 * Array.getLength : 数组长度 * Array.get(arr, 3):数组角标3的元素 */ @Test public void test5() throws Exception{ Object[] arr = new String[5]; for (int i = 0; i < arr.length; i++) { arr[i] = i +""; } Class class2 = arr.getClass(); if(class2.isArray()){ System.out.println(Array.getLength(arr)); System.out.println(Array.get(arr, 3)); } }
6、泛型反射
class Parent{} class Student extends Parent
转载地址:http://seuni.baihongyu.com/