我已经用了很多

System.getProperty("property")

为了获得环境信息。但是,在我看来,Sun更喜欢以下内容:
(String) java.security.AccessController.doPrivileged(
               new sun.security.action.GetPropertyAction("property"));

奇怪的是,此代码涉及强制转换,因此应比
System.getProperty
实现,它仅使用安全管理器,然后立即从实例变量props中获取属性。我的问题是,为什么Sun选择使用第二种方法从内部获取其代码中的大多数环境变量,而
System.getProperty
似乎是更快的方法?

最佳答案

两种方法的含义不同,因此必须根据当前代码的需要使用正确的方法。

代码System.getProperty("property")表示“如果当前的安全上下文允许我读取属性,请给我属性的值。”

使用doPrivileged的代码说:“如果允许当前类(代码所在的行)读取它,请给我属性的值。”

当当前类的保护域与当前 Activity 的安全上下文不同时,就会发挥作用。

例如,考虑一个执行插件代码的框架,该框架是不受信任的。因此,该框架使用SecurityManager来限制不受信任的插件代码的操作。但是,当然,该插件可以调用框架的某些方法,并假定这些方法之一需要读取属性。现在,由于从不受信任的受限代码中调用了该方法,因此它本身也受到了限制,因此读取该属性将失败。但是,当然,即使在调用堆栈中某处是不受信任的代码的情况下,框架也会信任自己并希望自己能够读取该属性。那是您需要使用doPrivileged的时候。它基本上说:“无论调用堆栈中有什么内容,我都是一部分框架代码,并且允许我做任何允许框架代码执行的事情”。因此,使用第二种方法读取属性成功。

当然,在使用doPrivileged时需要小心,以免让(不可信的)调用代码做太多事情。例如,如果框架代码为插件提供了以下方法:

public String getProp(String key) {
  return (String) java.security.AccessController.doPrivileged(
           new sun.security.action.GetPropertyAction(key));
}

这将完全使不允许不受信任的代码读取系统属性的策略无效,因为它只能使用您的方法。

因此,仅当您知道这样做是安全的,并且仅在需要时才使用此方法(也就是说,当您希望自己的代码能够比其他一些代码直接执行更多操作时)。在普通应用程序内(通常不使用SecurityManager或所有代码使用相同的安全上下文运行),没有区别,应使用第一种方法。

09-10 06:33
查看更多