【发布时间】:2013-05-14 03:43:55
【问题描述】:
最近我遇到了反射 API,令我惊讶的是我们可以访问甚至更改私有变量。我尝试了以下代码
import java.lang.reflect.Field;
public class SomeClass{
private String name = "John";
}
public class Test{
public static void main(String args[]) throws Exception {
SomeClass myClass = new SomeClass();
Field fs = myClass.getClass().getDeclaredField("name");
fs.setAccessible(true);
System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));
fs.set(myClass, "Sam");
System.out.println("Variable is " + fs.getName() + " and value is "
+ fs.get(myClass));
}
}
我得到了以下输出。
Variable is name and value is John
Variable is name and value is Sam
我们说Java是一种面向对象的语言,它的主要特性是数据封装、继承、多态......等等。反射API不是改变了数据封装的目的吗?为什么我们必须使用反射 API?我在一些网站上读到它可以用于测试目的,但根据我的说法,模块已经过测试,并且可以使用 JUnit 测试用例轻松完成。那么任何人都可以解释为什么我们有这样的黑客吗?
【问题讨论】:
-
反射 API 的实用工具之一是 IOC 模式,允许框架调用在其编译时(框架的)未知的方法。其他用途是检查类以执行转换(例如,直接从 bean 生成 SOAP 或 JSON 响应)
-
在您的代码中,您不必使用
fs.setAccessible(true);,因为您知道在同一类的其他方法中更改私有字段(可以访问每个字段,甚至是私有字段)。我稍微更改了您的示例,以表明通过反射您可以访问通常无法访问的私有字段。
标签: java reflection private encapsulation