Как ограничить setAccessible только «законным» использованием?
Чем больше я узнал о силеjava.lang.reflect.AccessibleObject.setAccessible
чем больше я удивляюсь тому, что он может сделать. Это адаптировано из моего ответа на вопрос (Использование отражения для изменения статического финала File.separatorChar для модульного тестирования).
import java.lang.reflect.*;
public class EverythingIsTrue {
static void setFinalStatic(Field field, Object newValue) throws Exception {
field.setAccessible(true);
Field modifiersField = Field.class.getDeclaredField("modifiers");
modifiersField.setAccessible(true);
modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
field.set(null, newValue);
}
public static void main(String args[]) throws Exception {
setFinalStatic(Boolean.class.getField("FALSE"), true);
System.out.format("Everything is %s", false); // "Everything is true"
}
}
Вы можете делать действительно возмутительные вещи:
public class UltimateAnswerToEverything {
static Integer[] ultimateAnswer() {
Integer[] ret = new Integer[256];
java.util.Arrays.fill(ret, 42);
return ret;
}
public static void main(String args[]) throws Exception {
EverythingIsTrue.setFinalStatic(
Class.forName("java.lang.Integer$IntegerCache")
.getDeclaredField("cache"),
ultimateAnswer()
);
System.out.format("6 * 9 = %d", 6 * 9); // "6 * 9 = 42"
}
}
Предположительно, дизайнеры API понимают, как можно злоупотреблятьsetAccessible
может быть, но должен был признать, что он имеет законное использование для его предоставления. Итак, мои вопросы:
setAccessible
?Может ли Java быть спроектирована так, чтобы НЕ иметь такую потребность?Каковы будут отрицательные последствия (если таковые имеются) такого дизайна?Вы можете ограничитьsetAccessible
только для законного использования?Это только черезSecurityManager
?Как это работает? Белый / черный список, гранулярность и т. Д.?Это часто приходится настраивать в своих приложениях?Могу ли я написать свои занятия, чтобы бытьsetAccessible
-защищенный независимо отSecurityManager
конфигурация?Или я во власти того, кто управляет конфигурацией?Я предполагаю, что еще один важный вопрос: нужно ли мне беспокоиться об этом ???
Ни у одного из моих классов нет никакого подобия принудительной неприкосновенности частной жизни вообще. Синглтон-паттерн (оставляя сомнения в его достоинствах) теперь невозможно применить. Как показывают мои фрагменты выше, даже некоторые базовые предположения о том, как работает фундаментальный Java, даже близко не гарантированы.
ЭТИ ПРОБЛЕМЫ НЕ РЕАЛЬНЫ ???
Хорошо, я только что подтвердил: спасибоsetAccessible
, Строки JavaНЕ неизменный.
import java.lang.reflect.*;
public class MutableStrings {
static void mutate(String s) throws Exception {
Field value = String.class.getDeclaredField("value");
value.setAccessible(true);
value.set(s, s.toUpperCase().toCharArray());
}
public static void main(String args[]) throws Exception {
final String s = "Hello world!";
System.out.println(s); // "Hello world!"
mutate(s);
System.out.println(s); // "HELLO WORLD!"
}
}
Я единственный, кто думает, что это ОГРОМНОЕ беспокойство?