Gücü hakkında java.lang.reflect.AccessibleObject.setAccessible
ne kadar çok şey öğrenirsem, yapabileceklerine o kadar çok şaşırıyorum. Bu soruya verdiğim yanıttan uyarlanmıştır ( Birim testi için statik nihai File.separatorChar'ı değiştirmek için yansıma kullanma ).
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"
}
}
Gerçekten acayip şeyler yapabilirsiniz:
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"
}
}
Muhtemelen API tasarımcıları ne kadar kötüye setAccessible
kullanılabileceğinin farkındadır , ancak bunu sağlamak için meşru kullanımları olduğunu kabul etmiş olmalıdır. Yani sorularım:
- Gerçekten meşru kullanım alanları
setAccessible
nelerdir?- Java ilk etapta bu ihtiyaca sahip OLMAYACAK şekilde tasarlanmış olabilir mi?
- Böyle bir tasarımın (varsa) olumsuz sonuçları ne olur?
setAccessible
Yalnızca meşru kullanımlarla sınırlayabilir misiniz?- Sadece içinden
SecurityManager
mi?- O nasıl çalışır? Beyaz liste / kara liste, ayrıntı düzeyi vb.
- Uygulamalarınızda yapılandırmak zorunda olmak yaygın mı?
- Sınıflarımı konfigürasyondan
setAccessible
bağımsız olarak yazabilir miyimSecurityManager
?- Yoksa konfigürasyonu yönetenin insafına mı kaldım?
- Sadece içinden
Sanırım bir önemli soru daha var: BU KONUDA DÜŞÜNMEM GEREKİYOR MU?
Sınıflarımdan hiçbiri, ne olursa olsun, uygulanabilir mahremiyete sahip değil. Singleton modelini (yararları hakkındaki şüpheleri bir kenara bırakarak) uygulamak artık imkansızdır. Yukarıdaki parçacıklarımın gösterdiği gibi, Java temelinin nasıl çalıştığına dair bazı temel varsayımlar bile garanti edilmeye yakın bile değil.
BU SORUNLAR GERÇEK DEĞİL Mİ ???
Tamam, şimdi onayladım: teşekkürler setAccessible
, Java dizeleri değişmez DEĞİLDİR .
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!"
}
}
Bunun BÜYÜK bir endişe olduğunu düşünen tek kişi ben miyim?