私有就是私有,为什么Java提供反射机制来访问私有方法?

9
使用反射时需要注意哪些潜在问题?我对反射很困惑,为什么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);
    }
}

请详细解释一下这种方法的应用场景?私有方法在其他类中可访问的优缺点是什么?


11
为什么可以通过反射访问Java私有字段? - peter.petrov
1
大多数常规项目不应需要任何反射,因为如果需要,您只需重新考虑您的架构即可(当然有例外情况)。我经常使用反射的一个地方是在单元测试中。您可以通过使用反射在UnitTests中更改私有字段来尝试多个场景。例如,一个布尔值。假设您有一个布尔设置,并且您想在UnitTest中测试两种情况。您项目中的默认值为false,因此首先进行测试。然后,您使用反射将其(临时)设置为true并测试另一种情况。 - Kevin Cruijssen
有人能举个例子解释一下吗?这样会更清楚我的概念。 - Avanish Singh
6
你在问题中标记了"security"。我认为你的误解在这里。访问控制修饰符并不是用作安全机制,而是用作面向对象设计工具。通过反射访问私有字段在你想要为代码的“常规”客户端提供适当封装的同时,仍希望使用框架(如JPA、依赖注入等)为你填充字段时非常有用。 - JB Nizet
1
@JimmyJames,我不是说安全不是个问题。我是说访问修饰符不是解决安全问题的答案。它们不是用来提供安全性的。它们是用来提供封装的。它们是一种设计工具。 - JB Nizet
显示剩余6条评论
2个回答

1
在大多数情况下,访问修饰符的作用是帮助隐藏您不希望其他人绑定的代码部分。使用反射访问私有方法可以从工具的角度提供便利。Java有一个安全机制,允许禁用此功能。此网站提供了一些关于与反射相关的Java安全模型的信息(页面底部)。
这只在您的代码将与不受信任的代码一起执行的情况下才真正重要。如果其他开发人员可以访问您的代码或库,则无法阻止他们在没有安全管理器或更改修饰符的情况下运行代码。这仅在受控环境中有效。

1
所有的“Private”和其他声明形式都是开发工具的标志,以便它知道你打算如何使用相关的字段或方法。这样,当开发人员以不预期的方式使用这些类/字段/方法时,开发工具可以向开发人员发出警告或错误信息。
反射是一种工具,它允许开发人员忽略或规避这些标志,表明你正在以从未预期的方式使用类/字段/方法。因此,一般来说,反射显示了糟糕的架构。
因此,将某些东西声明为私有或公共或静态没有“优点或缺点”,它们只是帮助保持代码干净和分隔的工具,只允许开发人员以特定的方式访问/使用你的类/字段/方法。

3
这是不正确的。当安全管理器存在时,JVM将执行可访问性限制(禁用反射绕过)。说这只是“编译时提示”是错误的;只是默认情况下未启用安全管理器(在存在SM的情况下构建应用程序更加困难)。一些非常有用的框架使用了这些反射功能,例如序列化类框架、分布式对象缓存、持久性框架和模拟框架。 - Brian Goetz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接