JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
当一个字节码文件加载到内存中的时候,jvm会对该字节码进行解剖,然后会创建一个对象的Class对象,把字节码文件的信息全部存储到该class对象中,我么只要获取到class对象,我们就可以使用字节码对象设置对象的属性或者调用对象的方法等操作...
利用反射可以反编译class文件或者获取java对象的属性方法构造函数等等信息。
#1. 获取反射class对象
>> 全路径获取[推荐]
>> 通过类名获取
>> 通过对象获取
/* * 获取class对象 */ // 方式一:全路径获取 [#推荐使用#] Class clazz1=Class.forName("com.wxh.reflect.Person"); System.out.println("class: "+clazz1);
// 方式二:通过类名获取 Class clazz2=Person.class; System.out.println("class: "+clazz2);
// 方式三:通过对象获取 Class clazz3=new Person("330122199312121900", "斯蒂芬", 22, new String[]{"篮球","足球","拉屎"}).getClass(); System.out.println("class: "+clazz3);
System.out.println("说明:因为是内存中只有一个对应的class对象,所以这三个class对象是一样的"); |
#2. 获取构造函数
>> getConstructor(class…) à获取某个共有的构造函数
>> getDeclaredConstructor(class…) à暴力获取某个构造函数
>> getConstructors() à获取所有的构造函数
>> getDeclaredConstructors() à暴力获取所有的构造函数
// 获取class对象所有public的构造函数 Constructor[] constructors = clazz.getConstructors(); for (Constructor constructor : constructors) { System.out.println("constructor: " + constructor); }
// 暴力获取class对象所有构造函数 Constructor[] constructors = clazz.getDeclaredConstructors(); for (Constructor constructor : constructors) { System.out.println("constructor: " + constructor); }
// 暴力获取class对象的某个private构造函数 Constructor constructor = clazz.getDeclaredConstructor(null); // 提高访问级别 constructor.setAccessible(true); // 初始化实例 Person p = (Person) constructor.newInstance(); System.out.println(p);
// 获取class对象的某个构造函数 Constructor constructor = clazz.getConstructor(String.class, String.class, int.class, String[].class); // 初始化实例 Person p = (Person) constructor.newInstance("330122199312121900", "斯蒂芬", 22, new String[] { "篮球", "足球", "拉屎" }); |
#3. 获取对象的方法
>> getMethod(String, class…) à获取对象的共有方法
>> getDeclaredMethod(String, class…) à暴力获取对象的方法
>> getMethods() à获取对象的所有公共方法
>> getDeclaredMethods() à暴力获取所有的公共方法
// 获取class对象的所有public方法[包括父类] Method[] methods = clazz.getMethods(); for (Method method : methods) { System.out.println(method); }
// 获取class对象的所有方法[不包括父类] Method[] methods = clazz.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); }
// 获取某个方法 Method method = clazz.getMethod("doSomething", String.class); method.invoke(p, "吃饭睡觉");
// 暴力获取private方法 Method method=clazz.getDeclaredMethod("getAge", null); // 设置权限 method.setAccessible(true); method.invoke(p, null); |
#4. 获取对象的属性
>> getField(String) à获取某个公共的字段
>> getDeclaredField(String) à暴力获取某个字段
>> getFields() à获取所有的公共字段
>> getDeclaredFields() à暴力获取所有的字段
// 获取所有的属性 Field[] fields=clazz.getFields(); for (Field field : fields) { System.out.println("Field: "+field); }
// 暴力获取所有的属性 Field[] fields=clazz.getDeclaredFields(); for (Field field : fields) { System.out.println("Field: "+field); }
// 获取某个属性 Field field =clazz.getField("idCard"); System.out.println("Field: "+field);
// 暴力获取某个属性 Field field=clazz.getDeclaredField("idCard"); field.setAccessible(true); System.out.println("Field: "+field); |
#5. 获取和设置属性的值
// 获取class对象 Class clazz = Class.forName("com.wxh.reflect.Person"); // 获取class对象的某个构造函数 Constructor constructor = clazz.getConstructor(String.class, String.class, int.class, String[].class); // 初始化实例 Person p = (Person) constructor.newInstance("330122199312121900", "斯蒂芬", 22, new String[] { "篮球", "足球", "拉屎" });
// 暴力获取某个属性 Field field=clazz.getDeclaredField("idCard"); field.setAccessible(true); System.out.println("Field: "+field);
// 设置p.idCard的属性值 field.set(p, "330122112134122200");
// 获取p.idCard属性的值 System.out.println("p.idCard: "+field.get(p)); |
#6. Person类
package com.wxh.reflect;
publicclass Person {
private String idCard; private String name; privateintage; private String[] hobby;
@SuppressWarnings("unused") private Person() { }
public Person(String idCard, String name, intage, String[] hobby) { super(); this.idCard = idCard; this.name = name; this.age = age; this.hobby = hobby; }
/* 获取爱好 */ public String[] getHobby() { returnthis.hobby; }
/* 获取年龄 */ @SuppressWarnings("unused") privatevoid getAge() { System.out.println("Age: " + this.age); }
publicvoid doSomething(String value) { System.out.println("今天要做的是:" + value); }
@Override public String toString() { return"ID Card: " + this.idCard + " | Name: " + this.name; } }
|
对于反射还有好多不理解的东西,主要接触太少,在实际中用的不多,等到以后接触多了,希望能有更加深入的了解。