【问题标题】:Private is Private, then Why java give facility to access private method using reflection? [duplicate]Private 是 Private,那么为什么 java 提供使用反射访问私有方法的便利? [复制]
【发布时间】:2015-10-16 07:50:27
【问题描述】:

使用反射时我需要注意哪些潜在问题。 我在反思中很困惑,为什么java提供这种类型的功能来访问私有数据成员。

私人: 就像我想的那样,只有声明它的类才能看到它。

那为什么可以访问其他类的私有内容呢? 这个术语(反射)完全超出了我对 java 中私有(访问说明符)属性的概念。

我访问了很多关于这个主题的链接,但没有给出关于这个主题的完整解释。 例如:

package example;

import java.lang.reflect.Method;

class A{
    private void privateMethod(){
        System.out.println("hello privateMethod()");
    }
}
class B{
    public static void main(String[] args) throws Exception {
        A d = new A();
        Method m = A.class.getDeclaredMethod("privateMethod");       
        m.setAccessible(true);
        m.invoke(d);
    }
}

那么请详细解释一下这种方法的场景? 我需要其他类中私有方法可访问性的优点和缺点吗?

【问题讨论】:

  • 大多数常规项目不需要任何反思,因为如果您这样做,您只需要重新考虑您的架构(当然也有例外)。我经常使用反射的一个地方是在 UnitTests 中。您可以通过使用 UnitTests 中的反射更改私有字段来简单地尝试多种方案。例如布尔值。假设您有一个布尔设置,并且您想在 UnitTest 中测试这两种情况。您项目中的默认值为 false,因此您首先对其进行测试。然后您使用反射将其(临时)设置为 true 并测试其他场景。
  • 谁能举个例子解释一下?因为它会非常清楚我的概念。
  • 您用“安全”标记了您的问题。我想这就是你的误解所在。访问修饰符并不意味着是一种安全机制。它们旨在成为一种面向对象的设计工具。当您想向代码的“常规”客户端提供正确封装的代码,但仍希望让框架(如 JPA、依赖注入等)为您填充字段时,通过反射访问私有字段非常有用。
  • @JimmyJames 我并不是说安全不是问题。我是说访问修饰符不是安全问题的答案。它们并不是为了提供安全性。它们旨在提供封装。它们是一种设计工具。

标签: java reflection


【解决方案1】:

所有“私有”和其他形式的声明都是开发工具的标志,以便它知道您打算如何使用相关字段或方法。这样开发工具可以在开发人员以非预期的方式使用这些类/字段/方法时向他们发出警告或错误。

Reflection 是一种工具,可让开发人员忽略或规避这些标志,这些标志表明您正在以一种从未想过的方式使用类/字段/方法。所以总的来说,反思表明架构不好。

因此,将某事物声明为私有、公共或静态没有“优点或缺点”;它们只是通过仅允许开发人员以特定方式访问/使用您的类/字段/方法来帮助保持代码清洁和划分的工具。

【讨论】:

  • 这是不正确的。当存在安全管理器时,JVM 将强制执行可访问性(禁用反射解决方法)。说这“只是”一个编译时提示是错误的;只是默认情况下未启用安全管理器(并且在 SM 存在的情况下构建应用程序更难)。这些反射特性被一些非常有用的框架使用,例如类似序列化的框架、分布式对象缓存、持久性框架和模拟框架。
【解决方案2】:

在大多数情况下,访问修饰符旨在帮助将您不希望人们绑定到的部分代码保持在视线之外。从工具的角度来看,使用反射访问私有方法的能力很有用。 Java 具有允许禁用此功能的安全机制。这个site有一些关于反射相关的java安全模型的信息(页面底部)。

这仅在您的代码将使用不受信任的代码执行的情况下才有意义。如果其他开发人员可以访问您的代码或拥有您的库,那么在没有安全管理器或更改修饰符的情况下,您无法阻止他们运行代码。这仅在受控环境中有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-17
    • 2010-12-21
    • 2012-11-04
    • 2021-03-14
    • 2011-06-01
    • 2011-02-08
    相关资源
    最近更新 更多