Подтвердить что ты не робот

GetPropertyAction vs System.getProperty в получении системных переменных

Я использую довольно много

System.getProperty("property")

для получения экологической информации. Однако мне кажется, что Sun предпочитает следующее:

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

Странно то, что этот код включает в себя литье, и в результате должен быть немного медленнее, чем

System.getProperty

который использует только диспетчера безопасности, а затем мгновенно извлекает свойство из реквизита переменной экземпляра. Мой вопрос заключается в том, почему Sun решила использовать второй метод для получения большинства переменных окружения в своем коде внутри, а

System.getProperty

кажется более быстрым способом?

4b9b3361

Ответ 1

Оба метода имеют различный смысл, и, следовательно, правильный должен использоваться в зависимости от того, что должен делать текущий код.

Код 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 или одного и того же контекста безопасности для всего кода), нет никакой разницы, и следует использовать первый метод.

Ответ 2

Я бы рекомендовал придерживаться System.getProperty(), поскольку sun.security.action.GetPropertyAction, похоже, принадлежит SUN и не будет работать во всех реализациях Java VM. Даже компилятор предупреждает вас об этом как:

warning: sun.security.action.GetPropertyAction - это собственный API Sun и может быть удален в будущем выпуске

Чтобы понять, что на самом деле означает видеть этот ответ.

Ответ 3

Причина использования класса, такого как sun.security.action.GetPropertyAction, заключается в том, чтобы избежать загрузки нескольких, в основном идентичных классов.

Если вы написали:

(String) java.security.AccessController.doPrivileged(
   new java.security.PrivilegedAction<java.lang.String>() {
      String run() {
         System.getProperty("property");
       }
   }
 );

Каждый раз, когда вы хотите получить системное свойство, вы должны загрузить новый класс для каждого вызова getProperty. Каждый класс принимает системные ресурсы и живет до тех пор, пока содержит класс ClassLoader (навсегда для bootclassloader).

Завершите вывод javap для получения более подробной информации:

javap -c -v -p sun.security.action.GetPropertyAction