这两种方法都有不同的含义,因此必须根据当前代码需要执行的操作使用正确的方法。
代码显示“如果当前安全上下文允许我读取该属性,请为我提供该属性的值。System.getProperty("property")
使用的代码显示“如果允许当前类(此行代码所在的位置)读取该属性,请为我提供该属性的值。doPrivileged
当当前类的保护域与当前活动的安全上下文不同时,差异就会发挥作用。
例如,考虑一个框架,它执行插件的代码,这是不受信任的。因此,该框架使用安全管理器来限制不受信任的插件代码的操作。但是,当然,插件可能会调用框架的某些方法,并假设这些方法之一需要读取属性。现在,由于该方法是从不受信任的受限代码调用的,因此它本身受到限制,因此读取属性将失败。但是,框架当然信任自己,并希望自己能够读取该属性,即使在调用堆栈中的某个地方是不受信任的代码的情况下也是如此。那是你需要使用的时候。它基本上是说“无论调用堆栈中有什么,我都是一段框架代码,我被允许做任何框架代码被允许做的事情”。因此,使用第二种方法读取属性会成功。doPrivileged
当然,在使用时需要小心,以免让(不受信任的)调用代码做很多事情。例如,如果框架代码为插件提供以下方法:doPrivileged
public String getProp(String key) {
return (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(key));
}
这将完全使不允许不受信任的代码读取系统属性的策略失效,因为它只能使用您的方法。
因此,仅当您知道这样做是安全的,并且仅当您需要它时才使用此方法(也就是说,当您希望您的代码能够比某些其他代码能够直接执行更多操作时)。在普通应用程序中(通常不使用 SecurityManager 或所有代码的相同安全上下文运行),没有区别,应使用第一种方法。