Java反射機制
在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個對象,都能夠調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。
Class類將一個類的組成封裝成各個屬性,並實現了各個getXxx()方法。
public static void getInfo(Class cls) throws NoSuchMethodException {
//構造方法
cls.getConstructor();
//包含的方法
cls.getMethods();
//包含的屬性
cls.getFields();
//實現的接口
cls.getInterfaces();
//包含的Annotation
cls.getAnnotations();
//內部類
cls.getDeclaredClasses();
//外部類
cls.getDeclaringClass();
//獲取類名
cls.getName();
//獲取包名
cls.getPackage();
//獲取修飾符
cls.getModifiers();
}
創建Person類
public class Person {
private String name;
private int age;
private String address;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
private void setAddress(String address){
this.address = address;
}
}
各種操作實現:
-
通過反射獲取類的三種方式
/**
* 通過反射獲取類的三種方式
* @throws ClassNotFoundException
*/
private void getClassWay() throws ClassNotFoundException {
Class cls = null;
cls = Person.class; //1
cls = new Person().getClass(); //2
cls = Class.forName("com.example.apple.Person"); //3
}
-
利用newInstance創建對象
/**
* 利用newInstance創建對象:調用的類必須有無參的構造器
* @param cls
*/
private void getInstance(Class cls){
try {
Person person = (Person) cls.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
-
獲取類所有方法
/**
* 獲取類所有方法(private修飾除外)
* @param cls
*/
public static void getMethods(Class cls){
Method[] methods = cls.getMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
-
獲取類聲明的方法
/**
* 獲取類聲明的方法
* @param cls
*/
public static void getAllMethods(Class cls){
Method[] methods = cls.getDeclaredMethods();
for(Method method : methods){
System.out.println(method.getName());
}
}
-
獲取指定方法
/**
* 獲取指定方法
* @param cls
* @throws NoSuchMethodException
*/
public static void getMethod(Class cls) throws NoSuchMethodException {
//第一個參數是方法名,後面參數依次是方法的參數類型
Method method = cls.getDeclaredMethod("setName",String.class);
System.out.println(method);
}
-
執行方法
/**
* 執行方法
* @param cls
*/
public static void invokMethod(Class cls) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Person person = (Person) cls.newInstance();
Method method = cls.getDeclaredMethod("setAddress",String.class);
//可以訪問對象的私有方法
method.setAccessible(true);
//invoke參數第一個,要調用方法的對象,後面對應爲各個參數
method.invoke(person,"北京海淀區");
}
-
操作屬性值
/**
* 操作屬性值
* @param cls
*/
public static void getFileds(Class cls) throws NoSuchFieldException, IllegalAccessException {
//獲取字段
Field[] fields = cls.getFields();
Field field = cls.getDeclaredField("address");
field.setAccessible(true);
//獲取指定對象指定屬性的值
Person person = new Person();
//設置指定對象的值
field.set(person,"北京海淀區");
}
-
獲取構造方法
public static void getConstructor(Class cls) throws NoSuchMethodException {
//獲取所有構造方法
Constructor[] constructors = cls.getConstructors();
//獲取所有構造方法(包括私有)
cls.getDeclaredConstructors();
//獲取指定參數對應類型的構造方法
cls.getDeclaredConstructor(String.class,Integer.class);
}