Оба метода имеют разное значение, и поэтому нужно использовать правильный, в зависимости от того, что должен делать текущий код.
Код System.getProperty("property")
говорит: «Дайте мне значение свойства,если текущий контекст безопасности позволяет мне читать его. "
Код, который использует doPrivileged
, говорит:" Дайте мне значение свойства, если разрешен текущий класс (в котором находится эта строка кода)чтобы прочитать его. "
Разница вступает в игру, когда домен защиты текущего класса отличается от текущего активного контекста безопасности.
Например, рассмотрим структуру, которая выполняет кодплагина, который не заслуживает доверия.Таким образом, платформа использует SecurityManager для ограничения действий кода ненадежного плагина.Но, конечно, плагин может вызывать некоторые методы фреймворка и предполагать, что один из этих методов должен прочитать свойство.Теперь, когда метод вызывается из недоверенного ограниченного кода, он сам по себе ограничен, и, таким образом, чтение свойства завершится неудачно.Но, конечно, фреймворк доверяет себе и хочет, чтобы он мог читать это свойство, даже в том случае, если где-то в стеке вызовов находится ненадежный код.Вот тогда вам нужно использовать doPrivileged
.По сути, он говорит: «Независимо от того, что находится в стеке вызовов, я являюсь частью кода фреймворка, и мне разрешено делать все, что разрешено делать фреймворку».Таким образом, чтение свойства с использованием второго метода завершается успешно.
Конечно, при использовании doPrivileged
нужно быть осторожным, чтобы не позволить (ненадежному) вызывающему коду многое сделать.Если, например, код платформы предлагает плагину следующий метод:
public String getProp(String key) {
return (String) java.security.AccessController.doPrivileged(
new sun.security.action.GetPropertyAction(key));
}
, это полностью аннулирует политику, согласно которой недоверенному коду не разрешается читать системные свойства, поскольку он может просто использовать ваш метод.
Так что используйте этот метод только тогда, когда вы знаете, что это безопасно, и только когда вам это нужно (то есть, когда вы хотите, чтобы ваш код мог выполнять больше, чем какой-либо другой код должен быть в состоянии).делать напрямую).Внутри обычного приложения (которое обычно выполняется без SecurityManager или с одинаковым контекстом безопасности для всего кода) нет разницы, и следует использовать первый метод.