Java中反射的"暴破"机制(SetAccessible方法)详解
更新时间:2022年08月16日 09:19:51 作者:Gao_小豆
这篇文章主要为大家详细介绍了Java中反射的"暴破"机制,以及如何利用这一机制实现访问非公有属性,方法,和构造器,文中示例代码讲解详细,感兴趣的可以了解一下
通过反射机制去访问类的属性,方法,构造器时,可以通过Class 的类的方法直接访问到对象的公有属性和私有属性,类属性等。当然这肯定违背了对象封装的意义,所以当通过反射机制去直接访问非公有属性,方法,和构造器时,均不能正常运行,如果想要正常执行代码,需要通过反射机制的“暴破”方法,强制进行访问。
具体的方法就是通过 setAccessible 方法直接设置为true就可以实现暴破。
1.通过反射访问构造器
package com.java.SetAcc; import java.lang.reflect.Constructor; public class ReflectCon { public static void main(String[] args) throws Exception { Class cls = Class.forName("com.java.SetAcc.Student"); //无参构造器创建实例 Object o2 = cls.newInstance(); System.out.println(o2); //访问公有带参构造器 Constructor constructor = cls.getConstructor(String.class); Object o = constructor.newInstance("AAA"); System.out.println(o); //访问私有的有参构造器 Constructor constructor1 = cls.getDeclaredConstructor(String.class,int.class); //暴破!!!! constructor1.setAccessible(true); Object o1 = constructor1.newInstance("bbb",12); System.out.println(o1); } } class Student{ public String name = "aaa"; public int age = 10; //无参构造 public Student() { } public Student(String name){ this.name = name; } private Student(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
2.通过反射访问类的属性
package com.java.SetAcc; import java.lang.reflect.Field; public class ReflectField_ { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("com.java.SetAcc.User"); //1. 访问无参 必须带无参构造器 Object o = cls.newInstance(); //访问public的属性 Field name = cls.getField("name"); //可以通过set修改值 name.set(o,"bbb"); System.out.println(name.get(o)); //2.访问私有属性 Field age = cls.getDeclaredField("age"); //暴破!!! 直接访问 age.setAccessible(true); age.set(o,12); System.out.println(o); //访问静态 Field salary = cls.getField("salary"); //可以通过null修改属性值 salary.set(null,2000); System.out.println(salary.get(null)); } } class User{ public String name = "aaa"; private int age = 10; public static double salary = 10000; public User() { } public User(String name, int age) { this.name = name; this.age = age; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
3.通过反射访问类的方法
package com.java.SetAcc; import java.lang.reflect.Method; public class ReflectMethod_ { public static void main(String[] args) throws Exception { Class<?> cls = Class.forName("com.java.SetAcc.Person"); Object o = cls.newInstance(); //公有方法 Method hi = cls.getMethod("hi", String.class); //调用的时候一定带上属性 hi.invoke(o,"aaa"); //私有方法 Method hello = cls.getDeclaredMethod("hello", int.class); hello.setAccessible(true); hello.invoke(o,10); //静态ff Method bye = cls.getDeclaredMethod("bye"); bye.setAccessible(true); bye.invoke(null); } } class Person{ public String name; public int age; public Person() { } public Person(String name, int age) { this.name = name; this.age = age; } public void hi(String name){ System.out.println("hi方法"+name); } private void hello(int age){ System.out.println("hello方法"+age); } static void bye(){ System.out.println("bye方法"); } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
到此这篇关于Java中反射的"暴破"机制(SetAccessible方法)详解的文章就介绍到这了,更多相关Java反射暴破机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
springcloud使用feign调用服务时参数内容过大问题
这篇文章主要介绍了springcloud使用feign调用服务时参数内容过大问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2022-03-03
最新评论