一、反射的定義
JAVA反射機制是在運行狀態中,可以構造任意一個類的對象,都能夠了解這個類的所有屬性和方法;
對於任意一個對象,都能夠調用它的任意方法和屬性;
這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。
二、反射的優點
提高了程序的靈活性和擴展性,降低模塊的耦合性,提高自身的適應能力。
可以讓程序創建和控制任何類的對象,無需提前硬編碼目標類。
能夠在運行時構造一個類的對象、判斷一個類所具有的成員變量和方法、調用一個對象的方法。
是構建框架技術的基礎所在,使用反射可以避免將代碼寫死在框架中。
三、反射的侷限性
反射操作的效率要比正常操作效率低很多。
使用反射通常需要程序的運行沒有安全方面的限制。
反射代碼破壞了Java程序結構的抽象性,反射允許代碼執行一些通常不被允許的操作,所以使用反射有可能會導致意想不到的後果。
四、反射機制的相關類
類名 | 用途 |
---|---|
Class類 | 代表類的實體,在運行的Java應用程序中表示類和接口 |
Field類 | 代表類的成員變量(成員變量也稱爲類的屬性) |
Method類 | 代表類的方法 |
Constructor類 | 代表類的構造方法 |
Class類
Class獲得類相關的方法
方法 | 用途 |
---|---|
asSubclass(Class<U> clazz) | 把傳遞的類的對象轉換成代表其子類的對象 |
Cast | 把對象轉換成代表類或是接口的對象 |
getClassLoader() | 獲得類的加載器 |
getClasses() | 返回一個數組,數組中包含該類中所有公共類和接口類的對象 |
getDeclaredClasses() | 返回一個數組,數組中包含該類中所有類和接口類的對象 |
forName(String className) | 根據類名返回類的對象 |
getName() | 獲得類的完整路徑名字 |
newInstance() | 創建類的實例 |
getPackage() | 獲得類的包 |
getSimpleName() | 獲得類的名字 |
getSuperclass() | 獲得當前類繼承的父類的名字 |
getInterfaces() | 獲得當前類實現的類或是接口 |
Class獲得類中屬性相關的方法
方法 | 用途 |
---|---|
getField(String name) | 獲得某個公有的屬性對象 |
getFields() | 獲得所有公有的屬性對象 |
getDeclaredField(String name) | 獲得某個屬性對象 |
getDeclaredFields() | 獲得所有屬性對象 |
Class獲得類中註解相關的方法
方法 | 用途 |
---|---|
getAnnotation(Class<A> annotationClass) | 返回該類中與參數類型匹配的公有註解對象 |
getAnnotations() | 返回該類所有的公有註解對象 |
getDeclaredAnnotation(Class<A> annotationClass) | 返回該類中與參數類型匹配的所有註解對象 |
getDeclaredAnnotations() | 返回該類所有的註解對象 |
Class獲得類中構造器相關的方法
方法 | 用途 |
---|---|
getConstructor(Class...<?> parameterTypes) | 獲得該類中與參數類型匹配的公有構造方法 |
getConstructors() | 獲得該類的所有公有構造方法 |
getDeclaredConstructor(Class...<?> parameterTypes) | 獲得該類中與參數類型匹配的構造方法 |
getDeclaredConstructors() | 獲得該類所有構造方法 |
Class獲得類中方法相關的方法
方法 | 用途 |
---|---|
getMethod(String name, Class...<?> parameterTypes) | 獲得該類某個公有的方法 |
getMethods() | 獲得該類所有公有的方法 |
getDeclaredMethod(String name, Class...<?> parameterTypes) | 獲得該類某個方法 |
getDeclaredMethods() | 獲得該類所有方法 |
Class類中其他重要的方法
方法 | 用途 |
---|---|
isAnnotation() | 如果是註解類型則返回true |
isAnnotationPresent(Class<? extends Annotation> annotationClass) | 如果是指定類型註解類型則返回true |
isAnonymousClass() | 如果是匿名類則返回true |
isArray() | 如果是一個數組類則返回true |
isEnum() | 如果是枚舉類則返回true |
isInstance(Object obj) | 如果obj是該類的實例則返回true |
isInterface() | 如果是接口類則返回true |
isLocalClass() | 如果是局部類則返回true |
isMemberClass() | 如果是內部類則返回true |
Field類
Field代表類的成員變量
方法 | 用途 |
---|---|
equals(Object obj) | 屬性與obj相等則返回true |
get(Object obj) | 獲得obj中對應的屬性值 |
set(Object obj, Object value) | 設置obj中對應屬性值 |
Method類
Method代表類的方法。
方法 | 用途 |
---|---|
invoke(Object obj, Object... args) | 傳遞object對象及參數調用該對象對應的方法 |
Constructor類
Constructor代表類的構造方法。
方法 | 用途 |
---|---|
newInstance(Object... initargs) | 根據傳遞的參數創建類的對象 |
五、反射的簡單實例
被反射的類Student
package com.xiaoxiao9575.reflectdemo;
import android.util.Log;
import androidx.annotation.NonNull;
/**
* author: xiaoxiao9575
* email: [email protected]
* csdn: https://blog.csdn.net/weixin_40998254
* github: https://github.com/xiaoxiao9575
* createTime: 2020/5/29 11:25 AM
*/
public class Student {
private String name;
private String sex;
private int age;
private static String info = "私有屬性";
public Student() {
}
private Student(String name, String sex, int age) {
this.name = name;
this.sex = sex;
this.age = age;
}
private String logInfo(String str){
Log.e("info", "logInfo: 私有方法"+ str);
return "私有方法"+ str;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", sex='" + sex + '\'' +
", age=" + age +
'}';
}
}
簡單的反射用例
package com.xiaoxiao9575.reflectdemo;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MainActivity extends AppCompatActivity {
private TextView textView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.textView);
textView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Test4();
}
});
}
/**
* 反射過程
*/
private void Test1(){
try {
Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
Object obj = classStudent.newInstance();
Student student = (Student) obj;
student.setName("張三");
student.setSex("男");
student.setAge(18);
Log.e("TAG", "Test1: =========="+student.toString() );
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 通過反射創建對象
*/
private void Test2(){
try {
Student student = (Student) Class.forName("com.xiaoxiao9575.reflectdemo.Student").newInstance();
student.setName("張三");
student.setSex("男");
student.setAge(18);
Log.e("TAG", "Test2: =========="+student.toString() );
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反射私有構造
*/
private void Test3(){
try {
Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
Constructor<?> declaredConstructor = classStudent.getDeclaredConstructor(String.class, String.class, int.class);
declaredConstructor.setAccessible(true);
Object obj = declaredConstructor.newInstance("李四", "女", 16);
Student student = (Student) obj;
Log.e("TAG", "Test3: =========="+student.toString() );
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反射私有屬性
*/
private void Test4(){
try {
Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
Object obj = classStudent.newInstance();
Field info = classStudent.getDeclaredField("info");
info.setAccessible(true);
String s = (String) info.get(obj);
Log.e("TAG", "Test4: =========="+s );
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反射私有方法
*/
private void Test5(){
try {
Class<?> classStudent = Class.forName("com.xiaoxiao9575.reflectdemo.Student");
Method logInfo = classStudent.getDeclaredMethod("logInfo", String.class);
logInfo.setAccessible(true);
Object object = classStudent.newInstance();
String test = (String) logInfo.invoke(object, "test");
Log.e("info", "Test5: =========="+test );
} catch (Exception e) {
Log.e("info", "Test5: =========="+e.getMessage() );
e.printStackTrace();
}
}
}