1、概述
是在運(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ǔ)言的反射機(jī)制。
2、獲取Class類對(duì)象的三種方式
- 類名.class屬性
- 對(duì)象名.getClass()方法
-
Class.forName(全類名)方法
//1.Class類中的靜態(tài)方法forName("全類名")
//全類名:包名 + 類名
Class clazz = Class.forName("com.Student");
System.out.println(clazz);
//2.通過(guò)class屬性來(lái)獲取
Class clazz2 = Student.class;
System.out.println(clazz2);
//3.利用對(duì)象的getClass方法來(lái)獲取class對(duì)象
//getClass方法是定義在Object類中.
Student s = new Student();
Class clazz3 = s.getClass();
System.out.println(clazz3);
3反射獲取構(gòu)造方法
| 方法名 |
說(shuō)明 |
| Constructor<?>[] getConstructors() |
返回所有公共構(gòu)造方法對(duì)象的數(shù)組 |
| Constructor<?>[] getDeclaredConstructors() |
返回所有構(gòu)造方法對(duì)象的數(shù)組 |
| Constructor<T> getConstructor(Class<?>... parameterTypes) |
返回單個(gè)公共構(gòu)造方法對(duì)象 |
| Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) |
返回單個(gè)構(gòu)造方法對(duì)象 |
Class clazz = Student.class;
System.out.print("返回所有構(gòu)造方法對(duì)象的數(shù)組:\n");
Constructor[] constructors1 = clazz.getConstructors();
for (Constructor constructor : constructors1) {
System.out.println(constructor);
}
System.out.printf("返回所有構(gòu)造方法對(duì)象的數(shù)組:\n");
Constructor[] constructors2 = clazz.getDeclaredConstructors();
for (Constructor constructor : constructors2) {
System.out.println(constructor);
}
//小括號(hào)中,一定要跟構(gòu)造方法的形參保持一致.
System.out.printf("返回單個(gè)構(gòu)造方法對(duì)象:\n");
Constructor constructor = clazz.getDeclaredConstructor();
System.out.println(constructor);
System.out.printf(" 返回單個(gè)公共構(gòu)造方法對(duì)象:\n");
Constructor constructor1 = clazz.getConstructor();
System.out.println(constructor1);
| 方法名 |
說(shuō)明 |
| T newInstance(Object...initargs) |
根據(jù)指定的構(gòu)造方法創(chuàng)建對(duì)象 |
| setAccessible(boolean flag) |
設(shè)置為true,表示取消訪問(wèn)檢查 |
static void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
//1.獲取class對(duì)象
Class clazz = Student.class;
//2.獲取一個(gè)私有化的構(gòu)造方法.
Constructor constructor = clazz.getDeclaredConstructor(String.class);
//被private修飾的成員,不能直接使用的
//如果用反射強(qiáng)行獲取并使用,需要臨時(shí)取消訪問(wèn)檢查
constructor.setAccessible(true);
//3.直接創(chuàng)建對(duì)象
Student student = (Student) constructor.newInstance("zhangsan");
System.out.println(student);
}
4反射獲取成員變量
| 方法名 |
說(shuō)明 |
| Field[] getFields() |
返回所有公共成員變量對(duì)象的數(shù)組 |
| Field[] getDeclaredFields() |
返回所有成員變量對(duì)象的數(shù)組 |
| Field getField(String name) |
返回單個(gè)公共成員變量對(duì)象 |
| Field getDeclaredField(String name) |
返回單個(gè)成員變量對(duì)象 |
static void test() throws NoSuchFieldException {
Class clazz = Student.class;
System.out.println("公共成員變量對(duì)象的數(shù)組:");
Field[] fields1 = clazz.getFields();
for (Field field : fields1) {
System.out.println(field);
}
System.out.println("返回所有成員變量對(duì)象的數(shù)組:");
Field[] fields2 = clazz.getDeclaredFields();
for (Field field : fields2) {
System.out.println(field);
}
//想要獲取的成員變量必須是真實(shí)存在的
//且必須是public修飾的.
System.out.println("單個(gè)公共成員變量對(duì)象:");
Field field1 = clazz.getField("name");
System.out.println(field1);
System.out.println("單個(gè)成員變量對(duì)象:");
Field field2 = clazz.getDeclaredField("money");
System.out.println(field2);
}
| 方法名 |
說(shuō)明 |
| void set(Object obj, Object value) |
賦值 |
| Object get(Object obj) |
獲取值 |
static void test() throws NoSuchFieldException, InstantiationException, IllegalAccessException {
Class clazz = Student.class;
//1先創(chuàng)建一個(gè)對(duì)象
Student student = (Student) clazz.newInstance();
//2.獲取成員變量Field的對(duì)象
Field field = clazz.getField("name");
//3有了對(duì)象才可以給指定對(duì)象進(jìn)行賦值
field.set(student,"zhangsan");
System.out.println(student);
//1創(chuàng)建一個(gè)對(duì)象
Student student2 = (Student) clazz.newInstance();
//2.獲取成員變量Field的對(duì)象
Field field2 = clazz.getDeclaredField("money");
//3.取消一下訪問(wèn)檢查
field2.setAccessible(true);
//4獲取指定對(duì)象的money的值
Object o = field.get(student);
//5.打印一下
System.out.println(o);
}
5、反射獲取成員方法并使用【應(yīng)用】
| 方法名 |
說(shuō)明 |
| Method[] getMethods() |
返回所有公共成員方法對(duì)象的數(shù)組,包括繼承的 |
| Method[] getDeclaredMethods() |
返回所有成員方法對(duì)象的數(shù)組,不包括繼承的 |
| Method getMethod(String name, Class<?>... parameterTypes) |
返回單個(gè)公共成員方法對(duì)象 |
| Method getDeclaredMethod(String name, Class<?>... parameterTypes) |
返回單個(gè)成員方法對(duì)象 |
static void test() throws NoSuchMethodException {
Class clazz = Student.class;
System.out.println("返回所有公共成員方法對(duì)象的數(shù)組,包括繼承的:");
Method[] methods1 = clazz.getMethods();
for (Method method : methods1) {
System.out.println(method);
}
System.out.println("返回所有成員方法對(duì)象的數(shù)組,不包括繼承的:");
Method[] methods2 = clazz.getDeclaredMethods();
for (Method method : methods2) {
System.out.println(method);
}
System.out.println("返回單個(gè)公共成員方法對(duì)象:");
Method method1 = clazz.getMethod("function1");
System.out.println(method1);
System.out.println("返回單個(gè)成員方法對(duì)象:");
Method method = clazz.getDeclaredMethod("show");
System.out.println(method);
}
- 運(yùn)行方法:
Object invoke(Object obj, Object... args)
參數(shù)一: 用obj對(duì)象調(diào)用該方法
參數(shù)二: 調(diào)用方法的傳遞的參數(shù)(如果沒(méi)有就不寫)
返回值: 方法的返回值(如果沒(méi)有就不寫)
static void test() throws NoSuchMethodException, InstantiationException, IllegalAccessException, InvocationTargetException {
//1.獲取class對(duì)象
Class clazz = Student.class;
//2.獲取里面的Method對(duì)象 function4
Method method = clazz.getMethod("function4", String.class);
//3.運(yùn)行function4方法就可以了
//3.1創(chuàng)建一個(gè)Student對(duì)象,當(dāng)做方法的調(diào)用者
Student student = (Student) clazz.newInstance();
//3.2運(yùn)行方法
Object result = method.invoke(student, "zhangsan");
//4.打印一下返回值
System.out.println(result);
}