Java如何通過反射獲取私有構造、私有對象、私有字段、私有方法

Java反射獲取私有構造、私有對象、私有字段、私有方法

1. 創建測試的私有對象

/**
 * @author lirong
 * @desc 測試對象
 * @date 2019/06/20 20:07
 */
public class Person {
    private int age = 5;
    private String name;
    private Person(){}
    private String test(String name){
        System.out.println("name: "+name);
        return "test";
    }
}

2. 獲取私有對象中的屬性和方法

/**
 * @author lirong
 * @desc 反射獲取私有屬性和方法
 * @date 2019/06/20 20:10
 */
public class Test {
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        // 1. 獲取class對象
        Class clazz = Person.class;
        // 2. 獲取私有無參構造
        Constructor c = clazz.getDeclaredConstructor();
        // 3. 設置訪問為可見
        c.setAccessible(true);
        // 4. 通過構造器創建實例對象
        Person person = (Person) c.newInstance();
        
        // 根據字段名稱獲取class中的字段
        Field age = clazz.getDeclaredField("age");
        age.setAccessible(true);
        System.out.println(age.getName() + " = " + age.get(person));
        // 修改私有變量的默認值
        age.set(person, 18);
        System.out.println(age.getName() + " = " + age.get(person));
        // 5. 獲取所有字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field f : fields) {
            // 設置字段的可見性
            f.setAccessible(true);
            String name = f.getName();
            Object o = f.get(person);
            System.out.println(name + " - " + o);
        }
        // 6. 獲取所有的方法
        Method[] methods = clazz.getDeclaredMethods();
        for (Method m : methods) {
            m.setAccessible(true);
            String name = m.getName();
            Object invoke = m.invoke(person, "張三");
            System.out.println(name + " = "+invoke);
        }
    }
}

通過反射獲取私有內部類對象

首先是我們的目標對象:

class Out {
    //目標獲取Inner對象
    private class Inner {
        //內部類的私有成員屬性
        private String inner = "ccc";
    }
}

直接列出代碼

public class Main {
    @SuppressWarnings({ "rawtypes", "unchecked" })
    public static void main(String[] args) throws Exception {
        //獲取外部類
        Class clzz = Out.class;
        //獲取外部類默認無參構造方法
        Constructor con = clzz.getDeclaredConstructor();
        //實例一個外部類對象
        Out outObj = (Out) con.newInstance();
        //獲取外部類內的所有內部類
        Class innerClazz[] = clzz.getDeclaredClasses();
        //遍歷
        for (Class c : innerClazz) {
            //獲取修飾符的整數編碼
            int mod = c.getModifiers();
            //返回整數編碼對應的修飾符的字符串對象
            String modifier = Modifier.toString(mod);
            //找到被private修飾的內部類
            if (modifier.contains("private")) {
                //根據內部類的特性,需要由外部類來反射獲取內部類的構造方法(這裡獲取的是內部類的默認構造方法)
                Constructor cc = c.getDeclaredConstructor(clzz);
                //由於內部類是私有的,需要強制獲取構造方法的訪問權限
                cc.setAccessible(true);
                //由外部類對象來反射獲取內部類的對象
                Object obj=cc.newInstance(outObj);
                //獲取內部類的私有成員屬性inner
                Field f=c.getDeclaredField("inner");
                //獲取訪問權限
                f.setAccessible(true);
                //獲取內部類對象obj中的私有成員屬性inner的值
                System.out.println(f.get(obj));
            }
        }
    }
}

輸出結果:

ccc

以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。

推薦閱讀: