一般咱們建立一個類時,它的私有方法在類外是不可見的,可是能夠經過反射機制來獲取調用。具體的反射機制的介紹你們本身百度。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()方法能夠繞過私有的安全檢查,因此咱們就能夠調用類的私有方法啦。ide