Gücü hakkında java.lang.reflect.AccessibleObject.setAccessiblene 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 setAccessiblekullanı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ı
setAccessiblenelerdir?- Java ilk etapta bu ihtiyaca sahip OLMAYACAK şekilde tasarlanmış olabilir mi?
- Böyle bir tasarımın (varsa) olumsuz sonuçları ne olur?
setAccessibleYalnızca meşru kullanımlarla sınırlayabilir misiniz?- Sadece içinden
SecurityManagermi?- 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
setAccessiblebağı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?