私人方法真的很安全吗?

在Java中, private访问修饰符被认为是安全的,因为它在类之外是不可见的。 那么外界也不知道这个方法。

但是我认为Javareflection可以用来打破这个规则。 考虑以下情况:

 public class ProtectedPrivacy{ private String getInfo(){ return "confidential"; } } 

现在从另外一个class级我将获得信息:

 public class BreakPrivacy{ public static void main(String[] args) throws Exception { ProtectedPrivacy protectedPrivacy = new ProtectedPrivacy(); Method method = protectedPrivacy.getClass().getDeclaredMethod("getInfo", null); method.setAccessible(true); Object result = method.invoke(protectedPrivacy); System.out.println(result.toString()); } } 

此时我只想到还有一些私人的方法,因为做了一些像上面这样的事情我们必须知道方法的名字。 但是如果包含其他人编写的私有方法的类我们没有这些可见性。

但是由于下面的代码,我的观点变得无效了。

 Method method[] = new ProtectedPrivacy().getClass().getDeclaredMethods(); 

现在这个method[]包含了所有需要做的事情。 我的问题是,有没有办法避免使用Javareflection这种事情?

我引用了Java文档中的一些观点来澄清我的问题。

关于select访问级别的提示:

如果其他程序员使用你的类,你想确保不会发生错误使用的错误。 访问级别可以帮助您做到这一点。使用对特定成员有意义的限制性最强的访问级别。 除非你有充分的理由不要私下使用。

这取决于你的意思是“安全”。 如果你正在运行一个安全pipe理器,允许这样的事情,那么是的,你可以用reflection来做各种令人讨厌的事情。 但是,在那样的环境下,图书馆可能只是被修改来公开方法。

访问控制在这样的环境中是有效的“咨询” – 你确实相信代码可以很好地发挥作用。 如果您信任正在运行的代码,则应该使用更严格的安全pipe理器。

访问修饰符与安全无关。 事实上,您可以也应该将访问修饰符视为安全性的反面 – 它不是保护您的数据或algorithm,而是保护人们不需要知道您的数据和algorithm。 这就是为什么默认修饰符是包 – 如果他们正在处理他们可能已经需要知道的包。

随着您的代码的数据和方法的知识,来了解何时以及如何使用它的响应。 你不要私下使用inIt方法来阻止某人发现它,你这样做是因为:(a)他们不会知道你只会在foo之后调用它,并且只有在bar = 3.1415和(b)因为这对他们不了解。

访问修饰符可以用一个简单的短语“TMI,老兄,我不需要知道这个”来概括。

通过说“安全”,您正在保护您或其他开发人员,通过调用您的私有方法来使用您的API不会损害对象。 但如果你或他们真的需要调用这个方法,他们可以用Reflection来完成。

问题是,你是从谁那里拯救出来的。 在我看来,这样的代码的客户端是在这里的一个损失。

任何试图访问上述类的private成员的代码(由你或其他人编写)本质上都是挖掘自己的坟墓。 private会员不参与公共 API,如有更改,恕不另行通知。 如果客户以上述方式使用这些私人成员之一,那么如果升级到私有成员被修改的API的更新版本,它将会中断。

随着设施,有责任。 有东西是你不能做的事情,你可以做的事情,但你不应该这样做。

私人修饰符以最受限制的方式被提供/使用。 在课堂以外不可见的成员应被定义为私人。 但是,我们可以看到,这可以通过reflection来打破。 但这并不意味着你不应该使用私人的,否则他们是不安全的。 这是关于你要审慎地或以build设性的方式(如反思)使用的东西。

假设你信任你的API的客户端程序员,另一种看待的方式是他们如何使用这些特定的function是“安全的”。

你公开的函数应该为你的代码提供一个清晰的,有详细logging的,很less变化的接口。 你的私有函数可以被认为是一个实现细节,可能会随着时间而改变,所以不直接使用安全。

如果一个客户程序员为了规避这些抽象而走出困境,他们会以某种方式宣称他们知道自己在做什么。 更重要的是,他们明白这是不受支持的,可能会停止使用未来版本的代码。

private不是为了安全,而是为了保持代码清洁,防止错误。 它允许用户模块化代码(以及如何开发),而不必担心其他模块的所有细节

一旦你释放你的代码,人们可以弄清楚它是如何工作的。 如果您最终希望代码在计算机上运行,​​则无法“隐藏”逻辑。 即使编译为二进制也只是一个混淆的级别。

所以,你不可能设置你的API来做一些你不希望别人能够调用的特殊的东西。 在Web API的情况下,您可以将要控制的方法放在服务器端。