为什么可以通过反射访问私有数据/类?

时间:2013-08-14 20:19:02

标签: java

在Java中,在运行时可以使用反射访问私有字段,也可以使用反射访问私有嵌套/内部类(例如,参见here)。有没有具体的技术原因,或任何一般的设计理念,这解释了为什么Java是这样的?我不知道,但从阅读this来看,对于C#/ .NET来说,至少在某些配置中,同样的事情是不可能的。 Java也有这种灵活性吗?是否存在无法实现的JVM实现?

当然,即使Java不允许通过反射访问私有字段,您也可以随时编写自己的运行时来执行任何操作。或者你可以修改二进制.jar / .class文件并更改访问修饰符(我认为这是可能的)。

因此,Java设计者必须选择三种可能性:

  1. 允许直接访问私人字段......可能会发出警告。
  2. 不允许直接访问私有字段,但允许使用反射访问私有字段。
  3. 不允许直接访问私有字段,也不允许使用反射访问私有字段。访问私有字段的唯一方法是更改​​运行时或脱机修改二进制.jar / .class文件。
  4. 选择中间对我来说似乎是任意的......如果目标是尽可能使其变得不方便,那么选择3是最好的。如果目标是不为无法真正阻止的事情增加人为的不便,那么1是最好的。

    是否有关于语言或运行时的信息或强制决定采取选择2?

2 个答案:

答案 0 :(得分:2)

从某种意义上说,是不是正在使用反射完全是你在#1中寻找的警告?

有时使用反射可以为其他繁琐的问题提供一些优雅的解决方案,GSON库如何创建和填充对象就是一个很好的例子。 “正常”代码不应该访问这些私有字段,并且使用反射允许您这样做,并且具有异常处理和权限修改的所有必要开销,以明确这不是在一般情况下要做的事情。

反射提供了比简单访问私有字段更多的功能。它允许您在运行时检查有关在编译时无法知道的类和对象的数据,并使用它们来调用方法并访问编译代码时不存在的字段。该行为的一个子集是私人访问。

所以,是的,Java设计人员可以为私有访问创建某种语法,但他们还需要创建反射,这是访问私有数据的更合理和更强大的方式;所有这一切都非常清楚(如果只是因为它很复杂),应该谨慎使用这种行为。对我来说,简单地调用object.privates.field或类似的东西并不意味着同样的严重性。

答案 1 :(得分:0)

有时您需要访问私有字段才能进行单元测试。比如在内部使用但不应直接调用的类中测试小型私有函数。其他时候,您可能想要检查内部数据结构是否包含正确的数据。

如果您出于其他原因使用反射作为访问私人数据的方法,您可能需要提出一个很好的理由这样做,因为大多数人审核您的代码(如果有的话)可能会注意到并且会出现作为一个红旗(该字段是私有的,有理由吗?)。

选择2可能是为了允许使用反射(可以在非调试版本中禁用)。