- Java的反射機(jī)制實(shí)在運(yùn)行狀態(tài)中,對(duì)于一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對(duì)于任意一個(gè)對(duì)象,都能夠調(diào)用它的方法和屬性,這種動(dòng)態(tài)獲取的獲取信息以及動(dòng)態(tài)調(diào)用對(duì)象的方法的功能稱為java語(yǔ)言的反射
- 想要解剖一個(gè)類,必須先要獲取該類的字節(jié)碼文件對(duì)象(類的信息都存儲(chǔ)在這里面了呢),解剖使用的就是Class類對(duì)象
1.1 獲取Class類型的對(duì)象
// 方式一: 獲取一個(gè)類字節(jié)碼文件對(duì)象
Person person = new Person("henson");
Class aClass = person.getClass();
// System.out.println(aClass);
// 方式二:
Class bClass = Person.class;
// 方式三:
// java.lang.ClassNotFoundException: Person
Class cClass = Class.forName("com.cskaoyan.reflection.Person");
1.2 通過(guò)反射獲取類構(gòu)造方法&&創(chuàng)建對(duì)象
// 1. 獲取類的字節(jié)碼文件對(duì)象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
//獲取public類型的
Constructor[] constructors = aClass.getConstructors();
//獲取所有類型的
Constructor[] declaredConstructors = aClass.getDeclaredConstructors();
for (Constructor c : declaredConstructors) {
System.out.println(c);
}
// 如何通過(guò) Construtor 對(duì)象生成對(duì)象
// T newInstance(Object... initargs) Object[] 參數(shù)個(gè)數(shù)可以是任意個(gè)(包括0個(gè))
// Uses the constructor represented by this Constructor object to create and initialize
// a new instance of the constructor's declaring class, with the specified initialization parameters.
// 獲取無(wú)參構(gòu)造方法
Constructor constructor = aClass.getConstructor();
Object o = constructor.newInstance();
System.out.println(o);
// 獲取兩個(gè)參數(shù)的構(gòu)造方法(public)
// Constructor<T> getConstructor(Class<?>... parameterTypes)
//獲取私有的方法;需要設(shè)置Access
Constructor constructor1 = aClass.getDeclaredConstructor(String.class, int.class);
// void setAccessible(boolean flag)
//Set the accessible flag for this object to the indicated boolean value.
constructor1.setAccessible(true);
// 自動(dòng)裝箱 拆箱 把基本數(shù)據(jù)自動(dòng)裝箱成相應(yīng)的引用數(shù)據(jù)類型 Integer
Object allen = constructor1.newInstance("Allen", 18);
System.out.println(allen);
}
通過(guò)反射獲取成員變量并使用
// 1. 獲取字節(jié)碼文件對(duì)象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
// 2. 通過(guò)字節(jié)碼文件對(duì)象獲取屬性(域)
// 獲取父類和自己公共的成員屬性和靜態(tài)屬性(public)
Field[] fields = aClass.getFields();
// 獲取自己定義的所有的成員屬性和靜態(tài)屬性(包括private)
Field[] declaredFields = aClass.getDeclaredFields();
/*
Person person = new Person();
person.name = "Trista"; //public
person.age = 18; //private
*/
Object o = aClass.newInstance();
System.out.println(o);
Field nameField = aClass.getField("name");
// 第一參數(shù):表示要對(duì)哪個(gè)對(duì)象進(jìn)行賦值
// 第二參數(shù):該對(duì)象的該屬性要新賦予的值
nameField.set(o, "Trista");
System.out.println(o);
// NoSuchFieldException: age,private類型
Field age = aClass.getDeclaredField("age");
age.setAccessible(true);
age.set(o, 18);
System.out.println(o);
}
獲取成員方法
//1 .獲取字節(jié)碼文件對(duì)象
Class aClass = Class.forName("com.cskaoyan.reflection.Person");
// 獲取父類和子類中公共的成員方法和靜態(tài)方法
Method[] methods = aClass.getMethods();
// 獲取該類中聲明的所有成員方法和靜態(tài)方法
Method[] declaredMethods = aClass.getDeclaredMethods();
Constructor declaredConstructor = aClass.getDeclaredConstructor(String.class, int.class);
declaredConstructor.setAccessible(true);
Object jenny = declaredConstructor.newInstance("Jenny", 18);
// Object invoke(Object obj, Object... args)
// 獲取某個(gè)方法
Method getAge = aClass.getMethod("getAge");
//相當(dāng)于對(duì)象.方法,(有參數(shù),再后面加上)
Object invoke = getAge.invoke(jenny); // 自動(dòng)拆箱
System.out.println(invoke);
//如果是private方法,設(shè)置Access
Method show = aClass.getDeclaredMethod("show");
show.setAccessible(true);
Object result = show.invoke(jenny);
System.out.println(result);
}
注:
通過(guò)反射訪問(wèn)類:
private Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
Person(String name) {
this.name = name;
}
private static void show() {
System.out.println("show self");
}
public int getAge() {
return age;
}