Ani*_*kur 8 java reflection encapsulation private
最近我遇到了Reflection 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));
}
}
Run Code Online (Sandbox Code Playgroud)
我得到了以下输出.
Variable is name and value is John
Variable is name and value is Sam
Run Code Online (Sandbox Code Playgroud)
我们说Java是一种面向对象的语言,它的主要特性是数据封装,继承,多态......等不是反射API改变了数据封装的目的吗?为什么我们必须使用Reflection API?我在一些网站上读到它可以用于测试目的,但据我说,模块已经过测试,可以使用JUnit测试用例轻松完成.所以任何人都可以解释为什么我们有这样的黑客攻击?
Ste*_*n C 11
反射API是不是改变了数据封装的目的?
是的,不是.
为什么我们必须使用Reflection API?
有许多反映出的使用不要破坏封装; 例如,使用反射来找出类具有的超类型,它具有哪些注释,它具有哪些成员,调用可访问的方法和构造函数,读取和更新可访问的字段等等.
并且有些情况可以接受(在不同程度上)使用封装破坏各种反射:
您可能需要查看封装类型(例如,访问/修改私有字段)作为实现某些单元测试的最简单方法(或唯一方式).
某些形式的依赖注入(也称为IoC),序列化和持久性需要访问和/或更新私有字段.
偶尔,您需要打破封装以解决某些类中无法修复的错误.
我在一些网站上读到它可以用于测试目的,但据我说,模块已经过测试,可以使用JUnit测试用例轻松完成.所以任何人都可以解释为什么我们有这样的黑客攻击?
这取决于你班级的设计.设计为可测试的类将是可测试的而无需访问"私有"状态,或者将暴露该状态(例如,protectedgetter)以允许测试.如果类没有这样做,那么JUnit测试可能需要使用反射来查看抽象内部.
这是不可取的(IMO),但如果您正在为某人编写的类编写单元测试,并且您无法"调整"API以提高可测试性,那么您可能必须在使用反射或根本不进行测试之间进行选择.
最重要的是数据封装是我们努力实现的理想(在Java中),但有些情况下,实际上正确的做法是打破它或忽略它.
请注意,并非所有OO语言都支持像Java那样强大的数据封装.例如,Python和Javascript都是无可争议的OO语言,但它们都使一个类可以轻松访问和修改另一个类的对象状态......甚至可以更改其他类的行为.强大的数据抽象并不是每个人对面向对象意味着什么的看法的核心.
| 归档时间: |
|
| 查看次数: |
2817 次 |
| 最近记录: |