暴力反射

通过反射,可以访问到一个类中的私有构造方法:

public class ReflectDemo{

  public static void main(String[ ] args){

 Class c = Class.forName("cn.demo.Person");

 Constructor[ ] cons = c.getDeclaredConstructors();

 for(Constructor con:cons){

 system.out.println(con);

//输出结果:(拿到所有的构造方法)


  Constructor con = c.getDeclaredConstructor(int.class,String.class);

  //值为true时取消访问权限,私有方法可以被调用,也叫暴力反射。

  con.setAccessible(true);

  Object obj = con.newInstance(18,"qiqi");

  system.out.println(obj);

  //输出结果:Person[name=qiqi,age=18]

 }

}

}


反射获取成员变量并改值
Class c = Class.forName("cn.demo.Person");
Fields[ ] fields = c.getFields();
for(Fields f: fields){
system.out.println(f);
//运行结果:获取到所有公共的成员变量
}

Field field = c.getField("name");
field.set(obj,"老王");
system.out.println(field);
//输出结果:Person[name=老王,age=0]
此时name属性就从null被改成了"老王"。



反射获取成员方法
1.无参

Class c = Class.farName(cn.demo.Person);
Object obj = c.newInstance();
Method [ ] methods = c.getMethods();
for(Method m:methods){
 system.out.println(m);
}
//运行结果:获取到所有的公共方法,包括继承的。

获取指定的方法,假如Person类中有个eat()方法:
Method method =c.getMethod("name");
method.invoke(obj);
//运行结果:人在吃


2.有参
Class c = Class.forName("cn.demo.Person");
Object obj = c.newInstance();
Method method = c.getMethod("sleep",String.class,int.class,double.class);

method.invoke(obj,"休眠",100,99.99)

//运行结果:人在睡觉  休眠 100  99.99



### Java中的暴力反射概念 暴力反射(Violent Reflection)指的是通过Java反射机制绕过类的访问控制权限,强制访问私有字段、方法或其他受保护的内容。这种技术通常用于测试或调试阶段,在某些特殊场景下可以突破封装原则来修改对象的状态。 #### 暴力反射的工作原理 在正常情况下,Java 的 `private` 和其他修饰符会限制外部代码对类成员的直接访问。然而,通过反射机制中的 `setAccessible(true)` 方法,开发者可以在运行时改变这些访问控制规则,使得原本不可见的成员变得可访问[^1]。此功能由 `java.lang.reflect.AccessibleObject` 类提供支持,它是一个抽象类,定义了如何设置访问标志的方法。 #### 实现暴力反射的具体步骤 以下是利用暴力反射访问和修改私有字段的一个典型例子: ```java import java.lang.reflect.Field; public class ViolentReflectionExample { public static void main(String[] args) throws Exception { // 创建目标对象 Person person = new Person(); // 获取Person类对应的Class对象 Class<?> clazz = person.getClass(); // 查找名为"name"的私有字段 Field field = clazz.getDeclaredField("name"); // 设置字段为可访问状态 (即开启暴力反射) field.setAccessible(true); // 修改私有字段的值 field.set(person, "John Doe"); // 输出结果验证更改是否成功 System.out.println(field.get(person)); // 输出: John Doe } } // 定义一个简单的类作为实验对象 class Person { private String name; // 私有字段 } ``` 上述代码展示了如何使用反射打破封装性,即使字段被声明为 `private`,仍然能够对其进行读写操作。这里的关键在于调用了 `field.setAccessible(true)` 这一语句[^2]。 #### 动态代理与暴力反射的关系 除了基本的操作外,当涉及到更复杂的动态代理需求时,也可以结合暴力反射完成特定的任务。比如创建接口实现的同时还需要处理一些隐藏逻辑,则可能需要用到类似的技巧去调整内部结构或者注入额外的行为[^3]。 需要注意的是,虽然这种方法非常强大,但它破坏了面向对象编程中关于数据隐蔽的原则,因此应该谨慎使用,并仅限于必要场合如单元测试工具开发等领域内应用。 ### 注意事项 尽管暴力反射提供了极大的灵活性,但在实际项目中应尽量避免滥用此类特性,因为这可能会带来维护困难以及潜在的安全隐患等问题。此外,自 JDK 9 起,默认加强了模块化系统的安全性措施,部分旧版依赖反射的方式或许不再适用,需重新评估解决方案[^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值