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()方法可以绕过私有的安全检查,所以我们就可以调用类的私有方法啦。