1、定義
JAVA反射機制是在運行狀態(tài)中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調(diào)用它的任意方法和屬性;這種動態(tài)獲取信息以及動態(tài)調(diào)用對象方法的功能稱為java語言的反射機制。
在日常的第三方應用開發(fā)過程中,經(jīng)常會遇到某個類的某個成員變量、方法或是屬性是私有的或是只對系統(tǒng)應用開放,這時候就可以利用Java的反射機制通過反射來獲取所需的私有成員或是方法。
2、反射相關類
類名 |
用途 |
Class類 |
代表類的實體,在運行的Java應用程序中表示類和接口 |
Field類 |
代表類的成員變量(成員變量也稱為類的屬性) |
Method類 |
代表類的方法 |
Constructor類 |
代表類的構造方法 |
2.1、Class類
Class類代表類的實體,在運行的Java應用程序中表示類和接口。在這個類中提供了很多有用的方法,這里對他們簡單的分類介紹。
2.1.1 、獲得類相關的方法
方法 |
作用 |
asSubclass(Class<U> clazz) |
把傳遞的類的對象轉換成代表其子類的對象 |
Cast |
把對象轉換成代表類或是接口的對象 |
getClassLoader() |
獲得類的加載器 |
getClasses() |
返回一個數(shù)組,數(shù)組中包含該類中所有公共類和接口類的對象 |
getDeclaredClasses() |
返回一個數(shù)組,數(shù)組中包含該類中所有類和接口類的對象 |
forName(String className) |
根據(jù)類名返回類的對象 |
getName() |
獲得類的完整路徑名字 |
newInstance() |
創(chuàng)建類的實例 |
getPackage() |
獲得類的包 |
getSimpleName() |
獲得類的名字 |
getSuperclass() |
獲得當前類繼承的父類的名字 |
getInterfaces() |
獲得當前類實現(xiàn)的類或是接口 |
2.1.2 、獲得類中屬性相關的方法
方法 |
作用 |
getField(String name) |
獲得某個公有的屬性對象 |
getFields() |
獲得所有公有的屬性對象 |
getDeclaredField(String name) |
獲得某個屬性對象 |
getDeclaredFields() |
獲得所有屬性對象 |
2.1.3 、獲得類中注解相關的方法
方法 |
作用 |
getAnnotation(Class<A> annotationClass) |
返回該類中與參數(shù)類型匹配的公有注解對象 |
getAnnotations() |
返回該類所有的公有注解對象 |
getDeclaredAnnotation(Class<A> annotationClass) |
返回該類中與參數(shù)類型匹配的所有注解對象 |
getDeclaredAnnotations() |
返回該類所有的注解對象 |
2.1.4 、獲得類中構造器相關的方法
方法 |
作用 |
getConstructor(Class...<?> parameterTypes) |
獲得該類中與參數(shù)類型匹配的公有構造方法 |
getConstructors() |
獲得該類的所有公有構造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) |
獲得該類中與參數(shù)類型匹配的構造方法 |
getDeclaredConstructors() |
獲得該類所有構造方法 |
2.1.5 、獲得類中方法相關的方法
方法 |
作用 |
getMethod(String name, Class...<?> parameterTypes) |
獲得該類某個公有的方法 |
getMethods() |
獲得該類所有公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) |
獲得該類某個方法 |
getDeclaredMethods() |
獲得該類所有方法 |
2.1.6 、類中其他重要的方法
方法 |
作用 |
isAnnotation() |
如果是注解類型則返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) |
如果是指定類型注解類型則返回true |
isAnonymousClass() |
如果是匿名類則返回true |
isArray() |
如果是一個數(shù)組類則返回true |
isEnum() |
如果是枚舉類則返回true |
isInstance(Object obj) |
如果obj是該類的實例則返回true |
isInterface() |
如果是接口類則返回true |
isLocalClass() |
如果是局部類則返回true |
isMemberClass() |
如果是內(nèi)部類則返回true |
2.2、Field類
Field代表類的成員變量(成員變量也稱為類的屬性)。
方法 |
作用 |
equals(Object obj) |
屬性與obj相等則返回true |
get(Object obj) |
獲得obj中對應的屬性值 |
set(Object obj, Object value) |
設置obj中對應屬性值 |
2.3、Method類
Method代表類的方法。
方法 |
作用 |
invoke(Object obj, Object... args) |
傳遞object對象及參數(shù)調(diào)用該對象對應的方法 |
2.4、Constructor類
Constructor代表類的構造方法。
方法 |
作用 |
newInstance(Object... initargs) |
根據(jù)傳遞的參數(shù)創(chuàng)建類的對象 |
3、示例
首先構造一個實體類Person.java,然后通過反射方法示例創(chuàng)建對象、反射私有構造方法、反射私有屬性、反射私有方法。
3.1、Person.java
package com.zjf.reflect;
public class Person {
private final static String TAG = "Person";
private String name;
private int age;
public Person() {}
private 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;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
private String privateMethod(int index) {
String string = null;
switch (index) {
case 0:
string = "param is 0";
break;
case 1:
string = "param is 1";
break;
default:
string = "param is 0";
}
return string;
}
}
3.2、反射方法
帶有Declared修飾的方法可以反射到私有的方法,沒有Declared修飾的只能用來反射公有的方法。
package com.zjf.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class ReflectUtils {
//通過反射創(chuàng)建對象
public static void reflectNewInstance() {
try {
Class<?> personClass = Class.forName("com.zjf.reflect.Person");
Object personObject = personClass.newInstance();//Person類中必須寫空參的構造方法
Person person = (Person) personObject;
person.setName("張俊峰");
person.setAge(25);
System.out.println("reflectNewInstance person == " + person.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//反射私有的構造方法
public static void reflectPrivateConstructor() {
try {
Class<?> personClass = Class.forName("com.zjf.reflect.Person");
//getDeclaredConstructor參數(shù)與構造方法的參數(shù)有關
Constructor<?> personConstructor = personClass.getDeclaredConstructor(String.class,int.class);
//暴力反射
personConstructor.setAccessible(true);
Person person = (Person)personConstructor.newInstance("朱偉",27);
System.out.println("reflectPrivateConstructor person == " + person.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//反射私有成員變量
public static void reflectPrivateField() {
try {
Class<?> personClass = Class.forName("com.zjf.reflect.Person");
Person person = (Person)personClass.newInstance();
person.setName("張小奔");
person.setAge(25);
Field tagField = personClass.getDeclaredField("TAG");//變量名
Field nameField = personClass.getDeclaredField("name");
tagField.setAccessible(true);
nameField.setAccessible(true);
System.out.println("reflectPrivateField tagField == " + (String)tagField.get(person));
System.out.println("reflectPrivateField nameField == " + (String)nameField.get(person));
nameField.set(person, "zjf");
System.out.println("reflectPrivateField person == " + person.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//反射私有方法
public static void reflectPrivateMethod() {
try {
Class<?> personClass = Class.forName("com.zjf.reflect.Person");
Person person = (Person)personClass.newInstance();
Method privateMethod = personClass.getDeclaredMethod("privateMethod", int.class);
privateMethod.setAccessible(true);
System.out.println("reflectPrivateMethod return == " + privateMethod.invoke(person, 0));
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4、總結