Java 反射獲取私有方法


通常我們創建一個類時,它的私有方法在類外是不可見的,但是可以通過反射機制來獲取調用。具體的反射機制的介紹大家自己百度。

所以反射可能會破壞我們的單例模式,當然解決方案也是有的,就是做個標記記錄次數,第二次調用私有構造器的時候拋出異常就可以了。這里就不詳細說明了。

首先我們創建一個需要被反射的類Person.java。它有默認構造器和帶參數構造器,以及私有方法。

package com.test;

/**
 * @program: java數據結構
 * @description: 人類
 * @author: Wu Lei
 * @create: 2018-10-25 09:58
 */
public class Person {
    private int age;
    private  String name;

    public Person(){};

    public Person(int age, String name){
        this.age = age;
        this.name = name;

    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public  void  say(){
        System.out.println("你好啊!公有方法!");
    }

    private void say2(){
        System.out.println("你好啊!私有方法!");
    }

    @Override
    public String toString() {
        return "Person{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}

創建一個測試類:

package com.test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @program: java數據結構
 * @description: java反射demo
 * @author: Wu Lei
 * @create: 2018-10-25 09:58
 */
public class ReflectionTest {
    public static void main(String[] args) {
        Class clazz = Person.class;
        Field [] fields =clazz.getDeclaredFields();
        System.out.println("獲取到的字段數組:");
        for(Field f : fields){
            System.out.println(f.toString());
        }
        try {
            Person p = (Person) clazz.newInstance();//調用默認構造方法
            p.setAge(15);
            p.setName("test");
            System.out.println("調用默認的構造方法:");
            System.out.println(p.toString());

            Constructor constructor = clazz.getDeclaredConstructor(int.class,String.class);//獲取指定參數類型的構造函數
            Person p2 = (Person) constructor.newInstance(13,"xiaoming");
            System.out.println("調用指定參數類型的構造方法:");
            System.out.println(p2);

            Method  method = clazz.getDeclaredMethod("say2");//獲取指定方法,包括私有方法
            method.setAccessible(true);//獲取私有權限
            method.invoke(p2);

            Method method1 = clazz.getMethod("say");//獲取有權限的方法,包括父類的
            method1.invoke(p);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

Method的setAccessible()方法可以繞過私有的安全檢查,所以我們就可以調用類的私有方法啦。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM