私人成员在Java中真的更“安全”吗?

时间:2012-02-08 21:20:15

标签: java oop

学习Java我有时会被教导使用private访问修饰符,以免将“敏感信息”暴露给其​​他类,就好像这可能会打开一个合法的安全漏洞。但是我从来没有遇到过限制成员可见性不仅仅是以面向对象的方式建模程序的便利的情况。

Java类中的private字段和函数实际上是否比其他更“安全”?


编辑 - 汇编最佳答案。

为什么private并不代表“安全”:

  • 反编译器允许静态查看字节码
  • reflection 库允许运行时访问私有成员

private有什么用处:

  • 由于强制方法级访问而导致的代码可维护性
  • 通过隐藏实现细节
  • 模块化代码

8 个答案:

答案 0 :(得分:8)

我从来没有听说过 - 在任何严重意义上 - 作为一个安全问题。我的意思是,反编译工作。您可以使用它们来弄清楚字节码内部发生了什么。

拥有private个成员是一个可维护性问题。如果我只给你方法级访问我的内部,那么我唯一的责任是确保我的API方法继续工作。我不会在内部使用DoubleBigDecimal,只要我的方法继续返回Double(例如)。

答案 1 :(得分:3)

不,从某种意义上说,它们并不是更“安全”,尽管有些(非常糟糕的)Java书试图以这种方式解释private。如果攻击者能够在您的进程中运行任意Java代码,那么所有“安全性”都已消失。正如另一个已经提到的答案,反射可以绕过private访问修饰符。

答案 2 :(得分:1)

private并不是真正的安全性,因为反射可以绕过它(模数类加载器/安全类加载器的东西)。它可以作为意图的指示,也可以作为一种编程错误的障碍。

但考虑使用第三方API - API用户甚至不会查看 private属性或方法。这不仅仅是关于你的自己的代码,而是代码暴露给他人的代码。 (再次从“我不打算闯入代码”的角度来看待它。)

答案 3 :(得分:1)

就安全性而言,答案是"不是真的":确定黑客可以通过一点反思来到你的私人领域并调用你的私人功能;他们需要的只是一个包含代码的JAR。

虽然隐藏敏感"信息不会使您的班级更加安全,它使得它(以及从它构建的系统)更多可维护。所以这个答案并不是让你所有班级成员公开的借口。

答案 4 :(得分:1)

我一般同意到目前为止的答案(即private实际上是代码卫生而不是真正的安全性)。各种答案都指出您可以使用反射绕过private。请注意,如果启用Java SecurityManager,则可以禁用反射。特别参见ReflectPermission。但是,很少使用安全管理器(在正常的浏览器沙盒之外)。

答案 5 :(得分:0)

显然,只有在遵守open-closed principle的情况下才能使所有内容成为私有的原则才适用。否则,如果人们习惯于编辑现有类的内部而不是扩展它们,那么它们可能会改变封装私有成员变量是通过mutator和accessors访问它们或更改访问修饰符。

答案 6 :(得分:0)

我认为你的导师“安全”的含义不是要让黑客出局,而是要防止出现问题。通过使所有内容尽可能私密,您可以限制一个类在没有它知道的情况下与另一个类混淆的方式。这是Modular Programming的一个例子。

答案 7 :(得分:0)

顺便说一句:Java中的反射实际上允许您覆盖对象字段的访问修饰符。请参阅javadocexample