Nhận giá trị của trường / thuộc tính cuối cùng tĩnh công khai của một lớp trong Java thông qua phản chiếu


103

Giả sử tôi có một lớp học:

public class R {
    public static final int _1st = 0x334455;
}

Làm cách nào để nhận giá trị của "_1st" thông qua phản xạ?


R._1stkhông thể hoạt động? Nếu bạn đang nói về phát triển Android, tôi nghĩ rằng Rlớp học luôn ở đó ...
Matthieu

@Matthieu Tôi cũng nghĩ vậy, cho đến ngày hôm nay khi tôi phải làm điều này rất giống, nhưng chỉ với BRlớp học.
Sevastyan Savanyuk

Câu trả lời:


132

Đầu tiên truy xuất thuộc tính trường của lớp, sau đó bạn có thể truy xuất giá trị. Nếu bạn biết kiểu, bạn có thể sử dụng một trong các phương thức get với null (chỉ đối với trường tĩnh, trên thực tế với trường tĩnh, đối số được truyền cho phương thức get sẽ bị bỏ qua hoàn toàn). Nếu không, bạn có thể sử dụng getType và viết một công tắc thích hợp như bên dưới:

Field f = R.class.getField("_1st");
Class<?> t = f.getType();
if(t == int.class){
    System.out.println(f.getInt(null));
}else if(t == double.class){
    System.out.println(f.getDouble(null));
}...

cảm ơn. Tôi đã thử nhưng nó không hoạt động. Ngoại lệ được ném vào hoạt động f.getInt (null). Tôi đã bắt được nó nhưng sao lại có một ngoại lệ?
Việt

1
Bạn đã nhận được loại ngoại lệ nào?
M. Jessup

Xin chào, Exception e.getMessage () trả về tên trường là "_1st" và không có gì khác.
Việt Nam

1
Nhưng loại ngoại lệ là gì? (tức là NullPointerException, SecurityException, ...)
M. Jessup

2
Tại sao tài liệu không bao giờ đề cập đến getInt()bỏ qua đối số được truyền vào? Đã dành hàng giờ để cố gắng làm cho phiên bản của lớp vượt qua đó.
Sevastyan Savanyuk

70
 R.class.getField("_1st").get(null);

Xử lý ngoại lệ được để lại như một bài tập cho người đọc.

Về cơ bản, bạn nhận được trường giống như bất kỳ trường nào khác thông qua phản chiếu, nhưng khi bạn gọi phương thức get, bạn chuyển vào giá trị null vì không có trường hợp nào để hành động.

Điều này hoạt động cho tất cả các trường tĩnh, bất kể chúng là trường cuối cùng. Nếu trường không công khai, bạn cần phải gọi setAccessible(true)nó trước và tất nhiên SecurityManager phải cho phép tất cả điều này.


Tôi hiểu rồi. Lớp tôi cần thực sự là R.id. Cảm ơn bạn đã giúp đỡ!
Việt

1

Tôi đã đi theo cùng một lộ trình (xem qua lớp R được tạo) và sau đó tôi có cảm giác khủng khiếp rằng nó có thể là một hàm trong lớp Tài nguyên. Tôi đã đúng.

Tìm thấy cái này: Tài nguyên :: getIdentifier

Nghĩ rằng nó có thể giúp mọi người tiết kiệm thời gian. Mặc dù họ nói rằng nó không được khuyến khích trong các tài liệu, điều này không quá ngạc nhiên.


Vì vậy, bạn suy ra đó là một câu hỏi Android. Đáng lẽ phải được chỉ định trong các thẻ ...
Matthieu

Đây không phải là một câu hỏi về Android, mà là một câu hỏi phản ánh Java sử dụng một ví dụ cụ thể. Các câu hỏi được gắn thẻ dựa trên chủ đề của họ.
Matthew Đọc
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.