什么是反射?
在JAVA中,對于任意一個運行中的對象,可以調用該對象的任意屬性和方法;已知一個類,可以獲取這個類的所有屬性和方法,這就是反射機制。
一般情況下,根據面向對象封裝原則,Java實體類的屬性都是私有的,我們不能獲取類中的屬性。但我們可以根據反射,獲取私有變量、方法、構造器,甚至是注解。
如何使用?
在最近的項目開發(fā)中,有一個需求:將人員檔案的80+個字段,設置部分為隱私字段,比如有權限可以看,權限需要動態(tài)分配。
我們不可能寫80個if - else,那么我就使用了Java反射,獲取人員檔案類的所有字段,并且將設置隱私字段的值全部set為“無權限訪問”
首先一點,我們根據類或者對象,就可以獲取class對象
User user = new User();
// 方式一 類獲取
Class userClass = User.class;
// 方式二 對象獲取
Class userClass2 = user.getClass();
// 方式三 靜態(tài)獲取
Class userClass3 = forName("zwz.pojo.User");
這個class對象是什么呢?
Java反射的所有內容,都是圍繞這個class對象展開
類
類完整路徑
String className = userClass.getName();
zwz.pojo.User
包路徑
String packagePath = userClass.getPackage().getName();
zwz.pojo
類名
String simpleClassName = userClass.getSimpleName();
User
獲取父類
String fatherClassName = userClass.getSuperclass().getSimpleName();
People
獲取接口
Class[] interfaces = userClass.getInterfaces();
根據class創(chuàng)建對象
User user1 = (User) userClass.getDeclaredConstructor().newInstance();
屬性
獲取單個屬性
// 獲取單個屬性
Field oneField = userClass.getDeclaredField("code");
// 獲取單個公有屬性
Field onePublicField = userClass.getField("grade");
獲取全部屬性
// 獲取全部屬性
Field[] fields = userClass.getDeclaredFields();
// 獲取全部公有屬性
Field[] publicFields = userClass.getFields();
for (Field field : fields) {
//讓我們在用反射時訪問私有變量
field.setAccessible(true);
// 屬性名
field.getName();
// 變量類型
field.getType().getName();
// 獲取對象中該屬性的值
field.get(user1);
// set 對象中該屬性的值
field.set(user1,"admin");
}
方法
獲取類中單個方法
// 獲取類中單個方法
Method publicMethod = userClass.getMethod("login", String.class, String.class);
// 獲取類中單個方法
Method method = userClass.getDeclaredMethod("login", String.class, String.class);
1234
獲取類所有方法
// 獲取類所有公有方法
Method[] methods = userClass.getMethods();
// 獲取類所有方法
Method[] publicMethods = userClass.getDeclaredMethods();
調用方法
// 對象 參數
method.invoke(new User(),"admin","123456");
構造器
獲取所有構造器
// 獲取所有公有構造器
Constructor[] publicConstructors = userClass.getDeclaredConstructors();
// 獲取所有構造器
Constructor[] constructors = userClass.getConstructors();
單個構造器
for (Constructor constructor : constructors) {
// 構造器名稱 等同類名
String name = constructor.getName();
// 構造器參數
Parameter[] parameters = constructor.getParameters();
}
使用構造器實例化對象
User user2 = (User) constructors[1].newInstance("admin", "123456", "95.8");
注解
獲取類的注解
Annotation[] annotations = userClass.getDeclaredAnnotations();
獲取字段的所有注解
Annotation[] anns = userClass.getDeclaredField("code").getAnnotations();
獲取字段的單個注解
Value annValue = userClass.getDeclaredField("code").getAnnotation(Value.class);
// 注解不存在返回 null
Controller annController = userClass.getDeclaredField("code").getAnnotation(Controller.class);
其他代碼
@Data
@AllArgsConstructor
@NoArgsConstructor
public class People {
private String name;
private int age;
public void sayHello(){
System.out.println("Hello ZWZ!");
}
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User extends People implements LoginMApper {
@Value("admin")
private String code;
@Value("123456")
private String password;
public String grade;
@Override
public boolean login(String code,String password){
if(code.equals("admin")&&password.equals("123456")){
System.out.println("code = " + code + "password = " + password + "登入成功");
return true;
}
System.out.println("code = " + code + "password = " + password + "登入失敗");
return false;
}
}
public interface LoginMapper {
boolean login(String code,String password);
}
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import zwz.pojo.User;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
public class ReflexTest {
public static void main(String[] args) throws Exception {
User user = new User();
// 方式一 類獲取
Class userClass = User.class;
// 方式二 對象獲取
Class userClass2 = user.getClass();
// 類完整路徑
String className = userClass.getName();
// 包路徑
String packagePath = userClass.getPackage().getName();
// 類名
String simpleClassName = userClass.getSimpleName();
// 獲取父類
String fatherClassName = userClass.getSuperclass().getSimpleName();
// 獲取接口
Class[] interfaces = userClass.getInterfaces();
// 根據class創(chuàng)建對象
User user1 = (User) userClass.getDeclaredConstructor().newInstance();
// 獲取單個屬性
Field oneField = userClass.getDeclaredField("code");
// 獲取單個公有屬性
Field onePublicField = userClass.getField("grade");
// 獲取全部屬性
Field[] fields = userClass.getDeclaredFields();
// 獲取全部公有屬性
Field[] publicFields = userClass.getFields();
for (Field field : fields) {
//讓我們在用反射時訪問私有變量
field.setAccessible(true);
// 屬性名
field.getName();
// 變量類型
field.getType().getName();
// 獲取對象中該屬性的值
field.get(user1);
// set 對象中該屬性的值
field.set(user1,"admin");
}
// 獲取類中單個公有方法
Method publicMethod = userClass.getMethod("login", String.class, String.class);
// 獲取類中單個方法
Method method = userClass.getDeclaredMethod("login", String.class, String.class);
// 獲取類所有公有方法
Method[] methods = userClass.getMethods();
// 獲取類所有方法
Method[] publicMethods = userClass.getDeclaredMethods();
// 運行方法
method.invoke(new User(),"admin","123456");
// 獲取公有構造器
Constructor[] publicConstructors = userClass.getDeclaredConstructors();
// 獲取所有構造器
Constructor[] constructors = userClass.getConstructors();
for (Constructor constructor : constructors) {
// 構造器名稱 等同類名
String name = constructor.getName();
// 構造器參數
Parameter[] parameters = constructor.getParameters();
}
User user2 = (User) constructors[1].newInstance("admin", "123456", "95.8");
// 獲取類的注解
Annotation[] annotations = userClass.getDeclaredAnnotations();
// 獲取字段的所有注解
Annotation[] anns = userClass.getDeclaredField("code").getAnnotations();
// 獲取字段的單個注解
Value annValue = userClass.getDeclaredField("code").getAnnotation(Value.class);
// 注解不存在返回 null
Controller annController = userClass.getDeclaredField("code").getAnnotation(Controller.class);
System.out.println("END!");
}
}
作者:鄭為中
原文鏈接:https://zwz99.blog.csdn.net/article/details/109248009