Càng tìm hiểu về sức mạnh của nó java.lang.reflect.AccessibleObject.setAccessible
, tôi càng ngạc nhiên về những gì nó có thể làm được. Điều này được điều chỉnh từ câu trả lời của tôi cho câu hỏi ( Sử dụng phản chiếu để thay đổi File.separatorChar tĩnh cuối cùng để kiểm tra đơn vị ).
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"
}
}
Bạn có thể làm những điều thực sự thái quá:
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"
}
}
Có lẽ các nhà thiết kế API nhận ra setAccessible
có thể bị lạm dụng như thế nào , nhưng phải thừa nhận rằng nó có các mục đích sử dụng hợp pháp để cung cấp. Vì vậy, câu hỏi của tôi là:
- Những mục đích sử dụng thực sự hợp pháp để làm
setAccessible
gì?- Có thể Java đã được thiết kế để KHÔNG có nhu cầu này ngay từ đầu?
- Hậu quả tiêu cực (nếu có) của thiết kế như vậy là gì?
- Bạn có thể
setAccessible
chỉ sử dụng hợp pháp không?- Là nó chỉ thông qua
SecurityManager
?- Làm thế nào nó hoạt động? Danh sách trắng / danh sách đen, mức độ chi tiết, v.v.?
- Có thường phải cấu hình nó trong các ứng dụng của bạn không?
- Tôi có thể viết các lớp của mình thành
setAccessible
-proof bất kểSecurityManager
cấu hình không?- Hay tôi đang phụ lòng của bất cứ ai quản lý cấu hình?
- Là nó chỉ thông qua
Tôi đoán còn một câu hỏi quan trọng nữa là: TÔI CÓ CẦN PHẢI LÀM VIỆC VỀ VIỆC NÀY KHÔNG ???
Không có lớp học nào của tôi có bất kỳ hình thức nào về quyền riêng tư có thể thực thi được. Mô hình singleton (đặt nghi ngờ về giá trị của nó sang một bên) hiện không thể thực thi. Như các đoạn trích của tôi ở trên cho thấy, ngay cả một số giả định cơ bản về cách hoạt động cơ bản của Java thậm chí còn không được đảm bảo.
NHỮNG VẤN ĐỀ NÀY KHÔNG CÓ THẬT ???
Được rồi, tôi vừa xác nhận: nhờ setAccessible
, các chuỗi Java KHÔNG bất biến.
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!"
}
}
Tôi có phải là người duy nhất nghĩ rằng đây là một mối quan tâm LỚN?