一骡男、概述
Java的反射機(jī)制是Java語言動態(tài)性的一種體現(xiàn)芭析。反射機(jī)制是通過反射API來實現(xiàn)的窗悯,它允許程序在運行過程中(runtime)取得任何一個已知名稱類的內(nèi)部信息瓶逃,包括其中的構(gòu)造方法、聲明的字段和定義的方法等丽已。這不得不說是一個很強大的能力蚌堵。
二、基本方法
說到反射的用法不得不提java.lang.Class類沛婴,通過該類的對象就的方法可以獲取到該類中的構(gòu)造方法吼畏、域和方法。對應(yīng)的方法分別是getConstructor嘁灯、getField和getMethod泻蚊。這三個方法還有相應(yīng)的getDeclaredXXX版本,區(qū)別在于getDeclaredXXX版本的方法會獲取該類自身所聲明的所有字段包括public, protected, default (package), 和 private丑婿,但不會獲取繼承下來的字段性雄。
Java反射API位于java.lang.reflect包中没卸。主要包括以下幾類:
- 1.Constructor類:用來描述一個類的構(gòu)造方法。
- 2.Field類:用來描述一個類的成員變量秒旋。
- 3.Method類:用來描述一個類的方法约计。
- 4.Modifer類:用來描述類內(nèi)各元素的修飾符。
- 5.Array:用來對數(shù)組進(jìn)行操作迁筛。
Constructor煤蚌、Field和Method這三個類分別表示類中的構(gòu)造方法、字段和方法细卧。
三尉桩、獲取類的構(gòu)造方法
java.lang.Class提供了4種獲取類構(gòu)造方法的反射調(diào)用:
- Constructor getConstructor(Class[] params) -通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法;
- Constructor[] getConstructors() -獲得類的所有公共構(gòu)造函數(shù)贪庙;
- Constructor getDeclaredConstructor(Class[] params) -獲得使用特定參數(shù)類型的構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法)蜘犁;
- Constructor[] getDeclaredConstructors() -獲得類的所有構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法);
調(diào)用這些方法會返回一個或多個 java.lang.reflect.Constructor 對象插勤。Constructor 類定義了newInstance 方法沽瘦,它采用一組對象作為其唯一的參數(shù)革骨,然后返回新創(chuàng)建的原始類實例农尖。該組對象是用于構(gòu)造函數(shù)調(diào)用的參數(shù)值。
3.1 獲取類的Class對象
方式一:通過將目標(biāo)類裝入到虛擬機(jī)的方式獲得該類的Class對象;
Class<?> cls=Class.forName("java.lang.String");
方式二:通過類或類的對象獲取類的Class對象;
Class<?> cls=String.class;
或
String str="";
Class<?> cls=str.getClass()
Class<?> cls=Class.forName("java.lang.String");
3.2 根據(jù)需要調(diào)用Class對象的4種獲取構(gòu)造方法的一種良哲,獲取到類的構(gòu)造方法
- 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法;
try {
Class<?> aClass = Class.forName("java.lang.String");
//1.獲取里面有特殊參數(shù)類型的公共構(gòu)造方法
Class[] parameterTypes = {String.class};
System.out.println("1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法");
Constructor<?> constructor = aClass.getConstructor(parameterTypes);
System.out.println("1---->constructor:"+constructor.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法
* 1---->constructor:public java.lang.String(java.lang.String)
*/
- 2.通過指定構(gòu)造參數(shù)獲取類的指定構(gòu)造方法,不是public的也會得到(不包含繼承的構(gòu)造方法)
try {
Class<?> aClass = Class.forName("java.lang.String");
Class[] parameterTypes = {char[].class, boolean.class};
System.out.println("2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法盛卡,該構(gòu)造方法不是繼承的");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(parameterTypes);
System.out.println("2---->declaredConstructor:"+declaredConstructor.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
*2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法,該構(gòu)造方法不是繼承的
*2---->declaredConstructor:java.lang.String(char[],boolean)
*/
- 3.獲取所有的公共構(gòu)造方法
String str = "";
Class<? extends String> aClass = str.getClass();
System.out.println("3.獲取所有的公共構(gòu)造方法:");
Constructor<?>[] constructors = aClass.getConstructors();
for (int i = 0 ;i<constructors.length;i++) {
System.out.println("總共:"+constructors.length+"筑凫,當(dāng)前第"+(i+1)+"個"+constructors[i].toString());
}
/**
* 打印結(jié)果如下:
* 3.獲取所有的公共構(gòu)造方法:
總共:15滑沧,當(dāng)前第1個public java.lang.String(byte[],int,int)
總共:15,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
總共:15巍实,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
總共:15滓技,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
總共:15,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
總共:15棚潦,當(dāng)前第6個public java.lang.String(java.lang.StringBuilder)
總共:15令漂,當(dāng)前第7個public java.lang.String(java.lang.StringBuffer)
總共:15,當(dāng)前第8個public java.lang.String(byte[])
總共:15丸边,當(dāng)前第9個public java.lang.String(int[],int,int)
總共:15叠必,當(dāng)前第10個public java.lang.String()
總共:15,當(dāng)前第11個public java.lang.String(char[])
總共:15妹窖,當(dāng)前第12個public java.lang.String(java.lang.String)
總共:15纬朝,當(dāng)前第13個public java.lang.String(char[],int,int)
總共:15,當(dāng)前第14個public java.lang.String(byte[],int)
總共:15骄呼,當(dāng)前第15個public java.lang.String(byte[],int,int,int)
*
*/
- 4.獲取所有類的構(gòu)造方法(不包含繼承的)
Class<String> stringClass = String.class;
System.out.println("4.獲取所有的構(gòu)造方法共苛,不包含繼承的");
Constructor<?>[] declaredConstructors = stringClass.getDeclaredConstructors();
for (int i = 0 ;i<declaredConstructors.length;i++) {
System.out.println("總共:"+declaredConstructors.length+"判没,當(dāng)前第"+(i+1)+"個"+declaredConstructors[i].toString());
}
/**
* 打印結(jié)果如下:
*4.獲取所有的構(gòu)造方法,不包含繼承的
總共:16隅茎,當(dāng)前第1個public java.lang.String(byte[],int,int)
總共:16哆致,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
總共:16,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
總共:16患膛,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
總共:16摊阀,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
總共:16,當(dāng)前第6個java.lang.String(char[],boolean)
總共:16踪蹬,當(dāng)前第7個public java.lang.String(java.lang.StringBuilder)
總共:16胞此,當(dāng)前第8個public java.lang.String(java.lang.StringBuffer)
總共:16,當(dāng)前第9個public java.lang.String(byte[])
總共:16跃捣,當(dāng)前第10個public java.lang.String(int[],int,int)
總共:16漱牵,當(dāng)前第11個public java.lang.String()
總共:16,當(dāng)前第12個public java.lang.String(char[])
總共:16疚漆,當(dāng)前第13個public java.lang.String(java.lang.String)
總共:16酣胀,當(dāng)前第14個public java.lang.String(char[],int,int)
總共:16,當(dāng)前第15個public java.lang.String(byte[],int)
總共:16娶聘,當(dāng)前第16個public java.lang.String(byte[],int,int,int)
*/
- 5.獲取類默認(rèn)的構(gòu)造方法
Class<String> stringClass = String.class;
System.out.println("5.獲取類默認(rèn)的構(gòu)造方法");
try {
Constructor<String> constructor = stringClass.getConstructor();
System.out.println("5---->默認(rèn)的構(gòu)造方法:"+constructor.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 5.獲取類默認(rèn)的構(gòu)造方法
*5---->默認(rèn)的構(gòu)造方法:public java.lang.String()
*/
四闻镶、通過反射獲取類的實例
上文中已經(jīng)通過反射獲取到類的構(gòu)造方法也就是Constructor對象。Constructor對象提供了public T newInstance(Object ... initargs)方法丸升,該方法返回類的實例铆农,其中initargs作為調(diào)用類的構(gòu)造方法的參數(shù)數(shù)組,反射API會根據(jù)數(shù)組中元素的類型和個數(shù)選擇調(diào)用類的相應(yīng)構(gòu)造方法狡耻。
Class<String> aClass = String.class;
System.out.println("通過指定構(gòu)造方法中參數(shù)類型墩剖,來獲取指定的構(gòu)造方法");
Class[] paramterType = {char[].class, boolean.class};
try {
Constructor<String> declaredConstructor = aClass.getDeclaredConstructor(paramterType);
System.out.println("declaredConstructor----->"+declaredConstructor.toString());
//告訴虛擬機(jī),當(dāng)調(diào)用該構(gòu)造方法時夷狰,不用進(jìn)行訪問權(quán)限的控制岭皂,也就是給反射開個綠燈;
declaredConstructor.setAccessible(true);
char[] chars = {'a',' ','s','t','u','d','e','n','t'};
Object newInstance = declaredConstructor.newInstance(chars, false);
System.out.println("-----object------->"+newInstance.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 通過指定構(gòu)造方法中參數(shù)類型,來獲取指定的構(gòu)造方法
*declaredConstructor----->java.lang.String(char[],boolean)
*-----object------->a student
*/
上面代碼中constructor2.setAccessible(true)的意思是告訴虛擬機(jī)沼头,當(dāng)調(diào)用該構(gòu)造方法時爷绘,不用進(jìn)行訪問權(quán)限的控制,也就是給反射開個綠燈瘫证。相應(yīng)地Method揉阎,F(xiàn)ield以及Constructor類都直接或間接的繼承了AccessibleObject類,該類提供了將反射的對象標(biāo)記為在使用時取消默認(rèn) Java 語言訪問控制檢查的能力背捌。所以說在使用Method毙籽,F(xiàn)ield以及Constructor類的對象時,如果該對象所表示的方法或字段是非public的毡庆,那么在訪問它之前需要調(diào)用 public void setAccessible(boolean flag)方法將該對象的訪問控制權(quán)限取消坑赡,否則java的異常處理機(jī)制會告訴你 can not access a member of class烙如。
五、通過反射獲取和修改類中的字段
和獲取類的構(gòu)造方法相似的是Class類同樣也提供了獲取類中字段的4種調(diào)用:
- 1.Field getField(String name) – 獲得命名的公共字段毅否;
- 2.Field[] getFields() – 獲得類的所有公共字段亚铁;
- 3.Field getDeclaredField(String name) – 獲得類聲明的命名的字段;
- 4.Field[] getDeclaredFields() – 獲得類聲明的所有字段螟加;
同樣getField與getFields可以獲得當(dāng)前類中以及繼承的public字段徘溢,getDeclaredField與getDeclaredFields則可以獲得當(dāng)前類中聲明的所有字段,但不能獲取繼承的字段捆探。
java.lang.reflect.Field表示類中的字段然爆,該類提供了getXXX 和 setXXX 方法,以及get 和 set 方法來獲取和設(shè)置該字段的值黍图。大家可以根據(jù)實際的字段類型自行選擇一種適當(dāng)?shù)姆椒ā?先看一下一會要用到的Person類曾雕,該類是一個簡單的JavaBean。
public class Person {
public String sex ;
}
public class Student extends Person{
private static int age ;
private static int width ;
private String name;
private int height ;
public static int getWidth() {
return width;
}
public static void setWidth(int width) {
Student.width = width;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 其他代碼省略
*/
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", height=" + height +
'}';
}
}
- 5.1 獲取指定字段
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
System.out.println("獲取指定字段");
try {
Field field = aClass.getDeclaredField("height");
field.setAccessible(true);
field.set(student,20);
System.out.println("----student--->"+student.toString());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* ----student--->Student{name='null', height=20}
*/
- 5.2 獲取類的所有字段
1.獲取該類以及繼承的所有公有字段;
System.out.println("獲取該類及繼承的所有公有字段");
Field[]fields=aClass.getFields();
for (int i = 0; i < fields.length; i++) {
System.out.println("總共:"+fields.length+"當(dāng)前第"+(i+1)+"個 "+fields[i].toString());
}
/**
* 打印結(jié)果:
* 獲取該類及繼承的所有公有字段
* 總共:1當(dāng)前第1個 public java.lang.String com.zcbl_videosurvey.test.Person.sex
*/
2.獲取該類所有的字段
System.out.println("獲取該類的所有字段助被,不包含繼承的");
Field[]fields2=aClass.getDeclaredFields();
for (int i = 0; i < fields2.length; i++) {
System.out.println("總共:"+fields2.length+"當(dāng)前第"+(i+1)+"個 "+fields2[i].toString());
}
/**
* 打印結(jié)果:
*總共:3當(dāng)前第1個 private static int com.zcbl_videosurvey.test.Student.age
*總共:3當(dāng)前第2個 private java.lang.String com.zcbl_videosurvey.test.Student.name
*總共:3當(dāng)前第3個 private int com.zcbl_videosurvey.test.Student.height
*/
需改字段
修非靜態(tài)字段
非靜態(tài)字段和方法屬于類的對象所有剖张,所以要修改類的非靜態(tài)字段需要一個該類的對象。
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
System.out.println("獲取指定字段");
try {
Field field = aClass.getDeclaredField("height");
field.setAccessible(true);
field.set(student,20);
System.out.println("----student--->"+student.toString());
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* ----student--->Student{name='null', height=20}
*/
需要指出的是如果字段是非public的揩环,需要在訪問該字段前取消該字段的訪問權(quán)限控制field.setAccessible(true)搔弄,那么對于一個final字段是否可以通過反射修改它的值呢,答案是肯定的检盼,前提同樣是在訪問該字段前取消該字段的訪問權(quán)限控制肯污。但如果該字段既被final修飾又被static修飾翘单,那么是無法修改的吨枉。
修改靜態(tài)字段
和修改非靜態(tài)字段相比,修改類的靜態(tài)字段就要輕松的多了哄芜,因為靜態(tài)字段屬于類所有貌亭,所以在修改靜態(tài)字段的時候就不需要再傳遞一個該類的對象了。
System.out.println("修改靜態(tài)字段");
try {
Field field = aClass.getDeclaredField("age");
field.setAccessible(true);
field.set(null,180);
System.out.println("-------->"+field.get(null));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 修改靜態(tài)字段
*-------->180
*/
六认臊、通過反射獲取并調(diào)用類中的方法
Class類提供了以下4種方式來獲取類中的方法:
- 1.Method getMethod(String name, Class[] params) – 使用特定的參數(shù)類型圃庭,獲得命名的公共方法;
- 2.Method[] getMethods() – 獲得類的所有公共方法失晴;
- 3.Method getDeclaredMethod(String name, Class[] params) – 使用特寫的參數(shù)類型剧腻,獲得類聲明的命名的方法;
- 4.Method[] getDeclaredMethods() – 獲得類聲明的所有方法涂屁;
與獲取類中字段類似书在,前兩個方法用于獲取類中以及繼承的所有公共方法 。后兩個方法用于獲取當(dāng)前類中(不包含繼承)所有的方法拆又。以上4種方法返回的是Method對象儒旬,Method類中提供了public Object invoke(Object obj, Object... args)通過該方法我們可以調(diào)用任何一個類的任何一個方法栏账。invoke 方法使用兩個參數(shù),為調(diào)用提供類實例和參數(shù)值數(shù)組栈源。
6.1 調(diào)用非靜態(tài)方法
Method類中提供了public Object invoke(Object obj, Object... args)通過該方法我們可以調(diào)用任何一個類的任何一個方法挡爵。invoke 方法使用兩個參數(shù),為調(diào)用提供類實例和參數(shù)值數(shù)組甚垦。如果第二個參數(shù)沒有茶鹃,可以省略或者null或者new Object[0];
Student student = new Student();
Class aClass = student.getClass();
try {
Method method = aClass.getMethod("setName", new Class[]{String.class});
method.invoke(student, "wanglu");
Method method1 = aClass.getMethod("getName", new Class[]{});
//第二個參數(shù)代表的參數(shù)數(shù)組值艰亮,如果沒有可以省略或者null或者new Object[0]
Object invoke = method1.invoke(student);
System.out.println("-------getName------>"+invoke.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* -------getName------>wanglu
*/
6.2 調(diào)用靜態(tài)方法
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
try {
Method method = aClass.getMethod("setAge", new Class[]{int.class});;
method.invoke(student, 20);
Method method1 = aClass.getMethod("getAge", new Class[]{});
Object invoke = method1.invoke(student);
System.out.println("-----調(diào)用靜態(tài)方法---->"+invoke.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("調(diào)用靜態(tài)的方法");
try {
Class<?> cls2 = Class.forName("java.lang.String");
Method method3=cls2.getMethod("valueOf", new Class[]{long.class});
//靜態(tài)方法屬于類方法前计,所以調(diào)用的時候可以將invoke的第一參數(shù)為null,但是不能省略不寫。
// Object object2=method3.invoke(null, 123);
Object object2=method3.invoke(student垃杖,123);
System.out.println(object2.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
*-----調(diào)用靜態(tài)方法---->20
* 調(diào)用靜態(tài)的方法
* 123
*/
靜態(tài)方法屬于類方法男杈,所以調(diào)用的時候可以將invoke的第一參數(shù)為null,但是不能省略不寫。
七调俘、通過反射動態(tài)創(chuàng)建和訪問數(shù)組
Class<?>componentType=Class.forName("java.lang.String");
Object array=Array.newInstance(componentType, 10);
Array.set(array, 5, "通過反射動態(tài)創(chuàng)建和訪問數(shù)組 ");
System.out.println(Array.get(array, 5));
上述代碼中Array.newInstance(componentType, 10);表示創(chuàng)建一個componentType類型大小為10的數(shù)組伶棒。Array.set(array, 5, "通過反射動態(tài)創(chuàng)建和訪問數(shù)組 ");表示將數(shù)組第6個元素修改為”通過反射動態(tài)創(chuàng)建和訪問數(shù)組 “,Array.get(array, 5)表示訪問數(shù)組中第6個元素的值彩库。
七肤无、反射實踐完整代碼
package com.zcbl_videosurvey.test;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by serenitynanian on 2018/2/23.
*/
public class Test {
public static void main(String[] args) {
//獲取類的Class對象
// getClassInstances();
/**
* 獲取類的構(gòu)造方法
* Constructor getConstructor(Class[] params) -- 獲取里面有特殊參數(shù)類型的公共構(gòu)造方法;
* Constructor[] getConstructors() -- 獲取該類的所有公共的構(gòu)造方法骇钦;
* Constructor getDeclaredConstructor(Class[] params) -- 獲取里面有特殊參數(shù)類型的構(gòu)造方法(不包含繼承的構(gòu)造方法)宛渐;
* Constructor[] getDeclaredConstructor() -- 獲取該類的所有構(gòu)造函數(shù)(不包含繼承的構(gòu)造方法);
*/
// getClassConstructor1();
// getClassConstructor2();
// getClassConstructor3();
// getClassConstructor4();
// getClassDefaultConstructor();
//通過反射獲取類的實例
// getReflectClassInstances();
//通過反射獲取字段
// getFiled();
//調(diào)用非靜態(tài)方法
// invokeNoStaticMethod();
//調(diào)用靜態(tài)方法
invokeStaticMethod();
}
private static void invokeStaticMethod() {
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
try {
Method method = aClass.getMethod("setAge", new Class[]{int.class});;
method.invoke(student, 20);
Method method1 = aClass.getMethod("getAge", new Class[]{});
Object invoke = method1.invoke(null);
System.out.println("-----調(diào)用靜態(tài)方法---->"+invoke.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
System.out.println("調(diào)用靜態(tài)的方法");
try {
Class<?> cls2 = Class.forName("java.lang.String");
Method method3=cls2.getMethod("valueOf", new Class[]{long.class});
Object object2=method3.invoke(null, 123);
System.out.println(object2.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
*-----調(diào)用靜態(tài)方法---->20
* 調(diào)用靜態(tài)的方法
* 123
*/
}
private static void invokeNoStaticMethod() {
Student student = new Student();
Class aClass = student.getClass();
try {
Method method = aClass.getMethod("setName", new Class[]{String.class});
method.invoke(student, "wanglu");
Method method1 = aClass.getMethod("getName", new Class[]{});
//第二個參數(shù)代表的參數(shù)數(shù)組值眯搭,如果沒有可以省略或者null或者new Object[0]
Object invoke = method1.invoke(student);
System.out.println("-------getName------>"+invoke.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* -------getName------>wanglu
*/
}
private static void getFiled() {
Student student = new Student();
Class<? extends Student> aClass = student.getClass();
// System.out.println("獲取指定字段");
// try {
// Field field = aClass.getDeclaredField("height");
// field.setAccessible(true);
// field.set(student,20);
// System.out.println("----student--->"+student.toString());
// } catch (NoSuchFieldException e) {
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// }
// /**
// * 打印結(jié)果:
// * ----student--->Student{name='null', height=20}
// */
// System.out.println("獲取該類及繼承的所有公有字段");
// Field[]fields=aClass.getFields();
// for (int i = 0; i < fields.length; i++) {
// System.out.println("總共:"+fields.length+"當(dāng)前第"+(i+1)+"個 "+fields[i].toString());
// }
// /**
// * 打印結(jié)果:
// * 獲取該類及繼承的所有公有字段
// * 總共:1當(dāng)前第1個 public java.lang.String com.zcbl_videosurvey.test.Person.sex
// */
// System.out.println("獲取該類的所有字段窥翩,不包含繼承的");
// Field[]fields2=aClass.getDeclaredFields();
// for (int i = 0; i < fields2.length; i++) {
// System.out.println("總共:"+fields2.length+"當(dāng)前第"+(i+1)+"個 "+fields2[i].toString());
// }
// /**
// * 打印結(jié)果:
// *總共:3當(dāng)前第1個 private static int com.zcbl_videosurvey.test.Student.age
// *總共:3當(dāng)前第2個 private java.lang.String com.zcbl_videosurvey.test.Student.name
// *總共:3當(dāng)前第3個 private int com.zcbl_videosurvey.test.Student.height
// */
System.out.println("修改指定的靜態(tài)字段");
try {
Field field = aClass.getDeclaredField("age");
field.setAccessible(true);
field.set(null,180);
System.out.println("-------->"+field.get(null));
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 修改靜態(tài)字段
*-------->180
*/
}
private static void getReflectClassInstances() {
Class<String> aClass = String.class;
System.out.println("通過指定構(gòu)造方法中參數(shù)類型,來獲取指定的構(gòu)造方法");
Class[] paramterType = {char[].class, boolean.class};
try {
Constructor<String> declaredConstructor = aClass.getDeclaredConstructor(paramterType);
System.out.println("declaredConstructor----->"+declaredConstructor.toString());
//告訴虛擬機(jī)鳞仙,當(dāng)調(diào)用該構(gòu)造方法時寇蚊,不用進(jìn)行訪問權(quán)限的控制,也就是給反射開個綠燈;
declaredConstructor.setAccessible(true);
char[] chars = {'a',' ','s','t','u','d','e','n','t'};
Object newInstance = declaredConstructor.newInstance(chars, false);
System.out.println("-----object------->"+newInstance.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 通過指定構(gòu)造方法中參數(shù)類型棍好,來獲取指定的構(gòu)造方法
*declaredConstructor----->java.lang.String(char[],boolean)
*-----object------->a student
*/
}
private static void getClassDefaultConstructor() {
Class<String> stringClass = String.class;
System.out.println("5.獲取類默認(rèn)的構(gòu)造方法");
try {
Constructor<String> constructor = stringClass.getConstructor();
System.out.println("5---->默認(rèn)的構(gòu)造方法:"+constructor.toString());
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 5.獲取類默認(rèn)的構(gòu)造方法
*5---->默認(rèn)的構(gòu)造方法:public java.lang.String()
*/
}
private static void getClassConstructor4() {
Class<String> stringClass = String.class;
System.out.println("4.獲取所有的構(gòu)造方法仗岸,不包含繼承的");
Constructor<?>[] declaredConstructors = stringClass.getDeclaredConstructors();
for (int i = 0 ;i<declaredConstructors.length;i++) {
System.out.println("總共:"+declaredConstructors.length+",當(dāng)前第"+(i+1)+"個"+declaredConstructors[i].toString());
}
/**
* 打印結(jié)果如下:
*4.獲取所有的構(gòu)造方法借笙,不包含繼承的
總共:16扒怖,當(dāng)前第1個public java.lang.String(byte[],int,int)
總共:16,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
總共:16业稼,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
總共:16盗痒,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
總共:16,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
總共:16盼忌,當(dāng)前第6個java.lang.String(char[],boolean)
總共:16积糯,當(dāng)前第7個public java.lang.String(java.lang.StringBuilder)
總共:16掂墓,當(dāng)前第8個public java.lang.String(java.lang.StringBuffer)
總共:16,當(dāng)前第9個public java.lang.String(byte[])
總共:16看成,當(dāng)前第10個public java.lang.String(int[],int,int)
總共:16君编,當(dāng)前第11個public java.lang.String()
總共:16,當(dāng)前第12個public java.lang.String(char[])
總共:16川慌,當(dāng)前第13個public java.lang.String(java.lang.String)
總共:16吃嘿,當(dāng)前第14個public java.lang.String(char[],int,int)
總共:16,當(dāng)前第15個public java.lang.String(byte[],int)
總共:16梦重,當(dāng)前第16個public java.lang.String(byte[],int,int,int)
*/
}
private static void getClassConstructor3() {
String str = "";
Class<? extends String> aClass = str.getClass();
System.out.println("3.獲取所有的公共構(gòu)造方法:");
Constructor<?>[] constructors = aClass.getConstructors();
for (int i = 0 ;i<constructors.length;i++) {
System.out.println("總共:"+constructors.length+"兑燥,當(dāng)前第"+(i+1)+"個"+constructors[i].toString());
}
/**
* 打印結(jié)果如下:
* 3.獲取所有的公共構(gòu)造方法:
總共:15,當(dāng)前第1個public java.lang.String(byte[],int,int)
總共:15琴拧,當(dāng)前第2個public java.lang.String(byte[],java.nio.charset.Charset)
總共:15降瞳,當(dāng)前第3個public java.lang.String(byte[],java.lang.String) throws java.io.UnsupportedEncodingException
總共:15,當(dāng)前第4個public java.lang.String(byte[],int,int,java.nio.charset.Charset)
總共:15蚓胸,當(dāng)前第5個public java.lang.String(byte[],int,int,java.lang.String) throws java.io.UnsupportedEncodingException
總共:15挣饥,當(dāng)前第6個public java.lang.String(java.lang.StringBuilder)
總共:15,當(dāng)前第7個public java.lang.String(java.lang.StringBuffer)
總共:15沛膳,當(dāng)前第8個public java.lang.String(byte[])
總共:15扔枫,當(dāng)前第9個public java.lang.String(int[],int,int)
總共:15,當(dāng)前第10個public java.lang.String()
總共:15锹安,當(dāng)前第11個public java.lang.String(char[])
總共:15短荐,當(dāng)前第12個public java.lang.String(java.lang.String)
總共:15,當(dāng)前第13個public java.lang.String(char[],int,int)
總共:15叹哭,當(dāng)前第14個public java.lang.String(byte[],int)
總共:15忍宋,當(dāng)前第15個public java.lang.String(byte[],int,int,int)
*
*/
}
private static void getClassConstructor2() {
try {
Class<?> aClass = Class.forName("java.lang.String");
Class[] parameterTypes = {char[].class, boolean.class};
System.out.println("2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法,該構(gòu)造方法不是繼承的");
Constructor<?> declaredConstructor = aClass.getDeclaredConstructor(parameterTypes);
System.out.println("2---->declaredConstructor:"+declaredConstructor.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
*2.通過指定構(gòu)造方法里面的參數(shù)類型獲取指定的構(gòu)造方法话速,該構(gòu)造方法不是繼承的
*2---->declaredConstructor:java.lang.String(char[],boolean)
*/
}
//獲取類的構(gòu)造方法
private static void getClassConstructor1() {
try {
Class<?> aClass = Class.forName("java.lang.String");
//1.獲取里面有特殊參數(shù)類型的公共構(gòu)造方法
Class[] parameterTypes = {String.class};
System.out.println("1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法");
Constructor<?> constructor = aClass.getConstructor(parameterTypes);
System.out.println("1---->constructor:"+constructor.toString());
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
/**
* 打印結(jié)果:
* 1.通過指定構(gòu)造方法里面的參數(shù)類型來獲取指定的公共構(gòu)造方法
* 1---->constructor:public java.lang.String(java.lang.String)
*/
}
//獲取類的Class對象
private static void getClassInstances() {
//1.方式一:通過將目標(biāo)類裝入到虛擬機(jī)的方式獲取該類的Class對象;
//此方式通常會用在:無法直接引用目標(biāo)類的情況讶踪;
try {
Class<?> aClass = Class.forName("java.lang.String");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//方式二:通過類或類的對象獲取類的Class對象
Class<String> stringClass1 = String.class;
//或者下面的方式
String str = "";
Class<? extends String> stringClass2 = str.getClass();
}
}