Giá trị của biến lớp cuối cùng tĩnh Java có thể được truy lục thông qua phản ánh không?Truy cập giá trị biến tĩnh cuối cùng của Java thông qua phản ánh
Trả lời
Tôi đoán rằng nó phụ thuộc vào loại và trình biên dịch
(trên suy nghĩ thứ hai, nó có chắc chắn tốt hơn không!). Trình biên dịch của Sun inline hằng số nguyên thủy, nhưng tôi không biết nếu họ loại bỏ hoàn toàn mục nhập từ lớp. Tôi sẽ tìm ra.
Chỉnh sửa: Có, bạn vẫn có thể truy cập ngay cả khi chúng được inlined. class Test:
public class ReflectionConstantTest {
private static final int CONST_INT = 100;
private static final String CONST_STRING = "String";
private static final Object CONST_OBJECT = new StringBuilder("xyz");
public static void main(String[] args) throws Exception {
int testInt = CONST_INT;
String testString = CONST_STRING;
Object testObj = CONST_OBJECT;
for (Field f : ReflectionConstantTest.class.getDeclaredFields()) {
f.setAccessible(true);
System.out.println(f.getName() + ": " + f.get(null));
}
}
}
Output:
CONST_INT: 100 CONST_STRING: String CONST_OBJECT: xyz
javap -c
đầu ra:
Compiled from "ReflectionConstantTest.java" public class scratch.ReflectionConstantTest extends java.lang.Object{ public scratch.ReflectionConstantTest(); Code: 0: aload_0 1: invokespecial #1; //Method java/lang/Object."":()V 4: return public static void main(java.lang.String[]) throws java.lang.Exception; Code: 0: bipush 100 2: istore_1 3: ldc #2; //String String 5: astore_2 6: getstatic #3; //Field CONST_OBJECT:Ljava/lang/Object; 9: astore_3 10: ldc_w #4; //class scratch/ReflectionConstantTest 13: invokevirtual #5; //Method java/lang/Class.getDeclaredFields:()[Ljava/lang/reflect/Field; 16: astore 4 18: aload 4 20: arraylength 21: istore 5 23: iconst_0 24: istore 6 26: iload 6 28: iload 5 30: if_icmpge 90 33: aload 4 35: iload 6 37: aaload 38: astore 7 40: aload 7 42: iconst_1 43: invokevirtual #6; //Method java/lang/reflect/Field.setAccessible:(Z)V 46: getstatic #7; //Field java/lang/System.out:Ljava/io/PrintStream; 49: new #8; //class java/lang/StringBuilder 52: dup 53: invokespecial #9; //Method java/lang/StringBuilder."":()V 56: aload 7 58: invokevirtual #10; //Method java/lang/reflect/Field.getName:()Ljava/lang/String; 61: invokevirtual #11; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 64: ldc #12; //String : 66: invokevirtual #11; //Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 69: aload 7 71: aconst_null 72: invokevirtual #13; //Method java/lang/reflect/Field.get:(Ljava/lang/Object;)Ljava/lang/Object; 75: invokevirtual #14; //Method java/lang/StringBuilder.append:(Ljava/lang/Object;)Ljava/lang/StringBuilder; 78: invokevirtual #15; //Method java/lang/StringBuilder.toString:()Ljava/lang/String; 81: invokevirtual #16; //Method java/io/PrintStream.println:(Ljava/lang/String;)V 84: iinc 6, 1 87: goto 26 90: return static {}; Code: 0: new #8; //class java/lang/StringBuilder 3: dup 4: ldc #17; //String xyz 6: invokespecial #18; //Method java/lang/StringBuilder."":(Ljava/lang/String;)V 9: putstatic #3; //Field CONST_OBJECT:Ljava/lang/Object; 12: return }
Bạn có thể thấy rằng CONST_INT
được sắp xếp theo hàng nhưng CONST_STRING
và CONST_OBJECT
(tất nhiên) thì không. Tuy nhiên, CONST_INT
vẫn có sẵn một cách phản ánh.
Có. (Chỉ không có những điều như tĩnh, chẳng hạn. Đó là tĩnh, không ví dụ.)
> If the underlying field is a static field, the obj argument is ignored; it may be null.
(bao gồm cảnh báo tiêu chuẩn mà hầu hết cách dùng phản ánh là một ý tưởng tồi)
Nếu open- thư viện nguồn được phép vào dự án của bạn, bạn có thể sử dụng
FieldUtils.readDeclaredStaticField
public class Test {
public final static String CONSTANT="myConstantValue";
}
Trong lớp khác, bạn có thể sử dụng:
Object value = FieldUtils.readDeclaredStaticField(Test.class, "CONSTANT");
System.out.println(value);
Bạn sẽ thấy "myConstantValue" trong giao diện điều khiển.
Chỉ nhận tên và giá trị không yêu cầu setAccessible (true). Dưới đây là ví dụ hữu ích khi bạn phải xử lý các hằng số được khai báo trong giao diện và muốn tên biểu tượng:
interface Code {
public static final int FOO = 0;
public static final int BAR = 1;
}
...
try {
for (Field field : Code.class.getDeclaredFields()) {
String name = field.getName();
int value = field.getInt(null);
System.out.println(name + "=" + value);
}
}
catch (IllegalAccessException e) {
System.out.println(e);
}
- 1. thay đổi các biến cuối cùng thông qua sự phản ánh, tại sao sự khác biệt giữa biến cuối cùng tĩnh và không tĩnh
- 2. Truy cập Bộ sưu tập Thông qua Phản ánh
- 3. Hai chủ đề, cùng một biến tĩnh, cùng một giá trị, truy cập đồng thời
- 4. Java: không thể truy cập vào các chú thích thông qua phản ánh
- 5. Biến cuối cùng tĩnh trong Java
- 6. Cách lấy giá trị chuỗi từ một trường Java thông qua sự phản ánh?
- 7. Truy cập các biến riêng tư trong Java thông qua sự phản chiếu
- 8. Tiếp cận tĩnh biến thức sử dụng phản ánh
- 9. unmarshal trên giá trị phản ánh
- 10. Các loại vô danh trong C# có thể truy cập thông qua phản ánh không?
- 11. C++ truy cập tĩnh const thông qua con trỏ NULL
- 12. C thiết lập giá trị tài sản thông qua phản ánh với các thuộc tính #
- 13. Sự khác nhau giữa biến tĩnh và biến tĩnh cuối cùng trong Java
- 14. Phản ánh trên Java
- 15. Nhận phản ánh giá trị của thuộc tính có getter có giá trị tùy chọn
- 16. Truy cập cặp khóa-giá trị cuối cùng bằng mã băm Ruby (1.9)
- 17. Truy cập giá trị của một biến theo tên của nó dưới dạng chuỗi trong Java
- 18. An toàn chủ đề nhưng nhanh chóng truy cập vào biến "cuối cùng cuối cùng"?
- 19. Truy cập các biến tĩnh
- 20. Cast thông qua phản ánh và sử dụng Class.cast()
- 21. Làm thế nào để truy cập vào lớp Java bên trong tĩnh thông qua Clojure interop?
- 22. Cập nhật biến tĩnh Java
- 23. Bảo vệ các biến số cuối cùng khỏi sự phản ánh
- 24. Getters cho biến cuối cùng
- 25. Gán giá trị mặc định cho biến cuối cùng trong trường hợp ngoại lệ trong Java
- 26. Biến tĩnh mất giá trị
- 27. Giá trị thay đổi Java của một biến thông qua một phương thức?
- 28. Công giá trị biến tĩnh
- 29. Truy cập biến tĩnh từ đối tượng trong Java
- 30. Truy cập tài sản tĩnh thông qua các phương pháp tĩnh và không tĩnh?
Điều này giải quyết được vấn đề của tôi! Tôi tò mò là tại sao chúng ta phải gọi f.setAccessible (true). Điểm của việc sửa đổi tĩnh không thể truy cập ở địa điểm đầu tiên là gì? – gsingh2011
@ gsingh2011: Lý do duy nhất cần thiết là chứng minh rằng thậm chí các hằng số riêng tư có thể được truy cập thông qua sự phản chiếu (bạn có thể quan sát thấy ba hằng số trong ví dụ được khai báo riêng). Các hằng số công khai sẽ không cần phải đặt có thể truy cập được vì chúng đã có thể truy cập được. –
Ahh, tôi hiểu rồi. Tôi chỉ nhận ra vấn đề của tôi xảy ra bởi vì tôi đã không cung cấp một công cụ sửa đổi công/tư nhân cho lĩnh vực của tôi, và sau đó refactored mã của tôi thành các gói. Cảm ơn anyway cho phản ứng. – gsingh2011