GetPropertyAction vs System.get获取系统变量时的属性

我一直在使用相当多的

System.getProperty("property")

为了获取环境信息。但是,在我看来,Sun更喜欢以下内容:

(String) java.security.AccessController.doPrivileged(
               new sun.security.action.GetPropertyAction("property"));

奇怪的是,这段代码涉及强制转换,因此应该比

System.getProperty

实现,它仅使用安全管理器,然后立即从实例变量 props 中获取属性。我的问题是,为什么Sun选择使用第二种方法在内部获取其代码中的大多数环境变量,而

System.getProperty

似乎是更快的方法?


答案 1

这两种方法都有不同的含义,因此必须根据当前代码需要执行的操作使用正确的方法。

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

使用的代码显示“如果允许当前类(此行代码所在的位置)读取该属性,请为我提供该属性的值。doPrivileged

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

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

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

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

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

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


答案 2

我建议坚持使用,因为似乎是SUN专有的,并且不适用于所有Java VM实现。甚至编译器也会警告你:System.getProperty()sun.security.action.GetPropertyAction

警告:sun.security.action.GetPropertyAction 是 Sun 专有的 API,可能会在将来的发行版中删除

要理解它的实际含义,请参阅此答案


推荐