ยิ่งฉันเรียนรู้เกี่ยวกับพลังของ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!"
}
}
Am I the only one who thinks this is a HUGE concern?