Java反射有多強? Ta擁有這五大神奇功能!

wxt020發表於2020-10-31

什麼是反射?


    在Java中,對於任意一個執行中的物件,可以呼叫該物件的任意屬性和方法; 已知一個類,可以獲取這個類的所有屬性和方法,這就是反射機制

    一般情況下,根據物件導向封裝原則,Java實體類的屬性都是私有的,我們不能獲取類中的屬性。但我們可以根據反射,獲取私有變數、方法、構造器,甚至是註解。https:

如何使用?

    在最近的專案開發中,有一個需求:將人員檔案的80+個欄位,設定部分為隱私欄位,比如有許可權可以看,許可權需要動態分配。

    我們不可能寫80個if - else,那麼我就使用了Java反射,獲取人員檔案類的所有欄位,並且將設定隱私欄位的值全部set為“無許可權訪問”

    首先一點,我們根據類或者物件,就可以獲取class物件

User user = new User();// 方式一 類獲取Class userClass = User.class;// 方式二 物件獲取Class userClass2 = user.getClass();// 方式三 靜態獲取Class userClass3 = forName("zwz.pojo.User");1234567

    這個class物件是什麼呢?

    Java反射的所有內容,都是圍繞這個class物件展開





類完整路徑

String className = userClass.getName();1
zwz.pojo.User1

包路徑

String packagePath = userClass.getPackage().getName();1
zwz.pojo1

類名

String simpleClassName = userClass.getSimpleName();1
User1

獲取父類

String fatherClassName = userClass.getSuperclass().getSimpleName();1
People1

獲取介面

Class[] interfaces = userClass.getInterfaces();1



根據class建立物件

User user1 = (User) userClass.getDeclaredConstructor().newInstance();1



獲取單個屬性

// 獲取單個屬性Field oneField = userClass.getDeclaredField("code");// 獲取單個公有屬性Field onePublicField = userClass.getField("grade");1234

在這裡插入圖片描述


獲取全部屬性

// 獲取全部屬性Field[] fields = userClass.getDeclaredFields();// 獲取全部公有屬性Field[] publicFields = userClass.getFields();1234
for (Field field : fields) {
    //讓我們在用反射時訪問私有變數
    field.setAccessible(true);
    // 屬性名
    field.getName();
    // 變數型別
    field.getType().getName();
    // 獲取物件中該屬性的值
    field.get(user1);
    // set 物件中該屬性的值
    field.set(user1,"admin");}123456789101112

方法


獲取類中單個方法

// 獲取類中單個方法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();1234

呼叫方法

// 物件 引數method.invoke(new User(),"admin","123456");12



構造器


獲取所有構造器

// 獲取所有公有構造器Constructor[] publicConstructors = userClass.getDeclaredConstructors();// 獲取所有構造器Constructor[] constructors = userClass.getConstructors();1234

單個構造器

for (Constructor constructor : constructors) {
    // 構造器名稱 等同類名
    String name = constructor.getName();
    // 構造器引數
    Parameter[] parameters = constructor.getParameters();}123456

使用構造器例項化物件

User user2 = (User) constructors[1].newInstance("admin", "123456", "95.8");1



註解


獲取類的註解

Annotation[] annotations = userClass.getDeclaredAnnotations();1

獲取欄位的所有註解

Annotation[] anns = userClass.getDeclaredField("code").getAnnotations();1

獲取欄位的單個註解

Value annValue = userClass.getDeclaredField("code").getAnnotation(Value.class);// 註解不存在返回 nullController annController = userClass.getDeclaredField("code").getAnnotation(Controller.class);123



其他程式碼


@Data@AllArgsConstructor@NoArgsConstructorpublic class People {
    private String name;
    private int age;
    public void sayHello(){
        System.out.println("Hello ZWZ!");
    }}12345678910

@Data@AllArgsConstructor@NoArgsConstructorpublic 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;
    }}1234567891011121314151617181920212223

public interface LoginMapper {
    boolean login(String code,String password);}123

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建立物件
        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!");
    }}1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69984164/viewspace-2731400/,如需轉載,請註明出處,否則將追究法律責任。

相關文章