Чим більше я дізнався про силу 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!"
}
}
Я єдиний, хто думає, що це ВЕЛИЧЕЗНА турбота?