Semakin banyak saya belajar tentang kekuatan java.lang.reflect.AccessibleObject.setAccessible
, semakin heran saya dengan apa yang bisa dilakukannya. Ini diadaptasi dari jawaban saya atas pertanyaan ( Menggunakan refleksi untuk mengubah File.separatorChar akhir statis untuk pengujian unit ).
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"
}
}
Anda dapat melakukan hal-hal yang sangat memalukan:
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"
}
}
Agaknya para perancang API menyadari betapa setAccessible
bisa disalahgunakannya , tetapi harus mengakui bahwa itu memiliki penggunaan yang sah untuk menyediakannya. Jadi pertanyaan saya adalah:
- Apa kegunaan yang benar-benar sah
setAccessible
?- Mungkinkah Java telah dirancang untuk TIDAK memiliki kebutuhan ini sejak awal?
- Apa konsekuensi negatif (jika ada) dari rancangan seperti itu?
- Bisakah Anda membatasi
setAccessible
untuk penggunaan yang sah saja?- Apakah hanya melalui
SecurityManager
?- Bagaimana cara kerjanya? Whitelist / blacklist, granularity, dll?
- Apakah umum untuk mengkonfigurasinya dalam aplikasi Anda?
- Dapatkah saya menulis kelas saya menjadi
setAccessible
-proof terlepas dariSecurityManager
konfigurasinya?- Atau apakah saya tergantung pada belas kasihan siapa pun yang mengelola konfigurasi?
- Apakah hanya melalui
Saya kira satu pertanyaan penting lagi adalah: APAKAH SAYA PERLU KHAWATIR TENTANG INI ???
Tak satu pun dari kelas saya yang memiliki privasi yang dapat diberlakukan apa pun. Pola tunggal (dengan mengesampingkan keraguan tentang manfaatnya) sekarang tidak mungkin untuk diterapkan. Seperti yang ditunjukkan cuplikan saya di atas, bahkan beberapa asumsi dasar tentang cara kerja fundamental Java bahkan tidak dijamin.
APAKAH MASALAH INI TIDAK NYATA ???
Oke, saya baru saja mengonfirmasi: terima kasih setAccessible
, string Java TIDAK dapat diubah.
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!"
}
}
Apakah saya satu-satunya yang berpikir bahwa ini adalah masalah yang BESAR?