Como limitar setAccessible apenas para usos "legítimos"?
Quanto mais eu aprendia sobre o poder dejava.lang.reflect.AccessibleObject.setAccessible
, mais espantado fico com o que ele pode fazer. Isso é adaptado da minha resposta à pergunta (Usando reflexão para alterar o File.separatorChar final estático para teste de unidade)
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"
}
}
Você pode fazer coisas realmente ultrajantes:
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"
}
}
Presumivelmente, os designers da API percebem o quão abusávelsetAccessible
pode ser, mas deve ter admitido que possui usos legítimos para fornecê-lo. Então, minhas perguntas são:
setAccessible
?Java poderia ter sido projetado para não ter essa necessidade em primeiro lugar?Quais seriam as consequências negativas (se houver) desse projeto?Você pode restringirsetAccessible
legitimar apenas usos?É apenas atravésSecurityManager
?Como funciona? Lista de permissões / lista negra, granularidade, etc?É comum ter que configurá-lo em seus aplicativos?Posso escrever minhas aulas para seremsetAccessible
à prova de qualquerSecurityManager
configuração?Ou estou à mercê de quem gerencia a configuração?Acho que mais uma pergunta importante é: PRECISO PREOCUPAR COM ISSO ???
Nenhuma das minhas aulas tem qualquer aparência de privacidade forçada. O padrão singleton (colocando dúvidas sobre seus méritos de lado) agora é impossível de impor. Como mostram meus trechos acima, mesmo algumas suposições básicas de como o Java fundamental funciona nem sequer estão garantidas.
ESTES PROBLEMAS NÃO SÃO REAIS ???
Ok, acabei de confirmar: graças asetAccessible
, Cadeias Java sãoNÃO imutável.
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!"
}
}
Eu sou o único que acha que isso é uma preocupação enorme?