私有方法真的安全吗?

2022-08-31 11:08:36

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

但我认为Java反射可以用来打破这个规则。请考虑以下情况:

public class ProtectedPrivacy{

  private String getInfo(){
     return "confidential"; 
  }

}  

现在从另一个班级,我将得到信息:

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();

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

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

有关选择访问级别的提示:

如果其他程序员使用您的类,您希望确保不会发生误用错误。访问级别可以帮助您执行此操作。使用对特定成员有意义的最严格的访问级别。除非您有充分的理由不使用,否则请使用私有。


答案 1

这取决于你所说的“安全”是什么意思。如果你正在运行一个允许这种事情的安全管理器,那么是的,你可以用反射做各种令人讨厌的事情。但是,在这种环境中,库可能只是被修改以使该方法公开。

在这样的环境中,访问控制实际上是“建议性的” - 您有效地信任代码可以很好地运行。如果您信任正在运行的代码,则应使用限制性更强的安全管理器。


答案 2

访问修饰符与安全性无关。事实上,你可以而且应该把访问修饰符看作是安全的反面 —— 它不是为了保护你的数据或算法,而是为了保护人们不需要了解你的数据和算法。这就是为什么默认修饰符是包的原因 - 如果他们正在处理包,他们可能已经需要知道了。

除了对数据和代码方法的了解外,还负责知道何时以及如何使用它。你不会在你的inIt方法上设置私有以防止某人发现它,你这样做是因为(a)他们不会知道你只在foo之后调用它,只有当bar = 3.1415和(b)因为它对他们没有什么好处知道他们。

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