2012-06-19 25 views
11
class Test { 
    public static void main(String[] args) throws Exception { 
     Test t = new Test(); 
     System.out.println(t.field); 
     System.out.println(t.getClass().getField("field").get(t)); 

     int[] ar = new int[23]; 
     System.out.println(ar.length); 
     System.out.println(ar.getClass().getField("length").get(ar)); 

    } 
    public int field = 10; 
}; 

Khi tôi chạy đoạn mã trên, tôi nhận được kết quả sau trên dòng lệnh -Bắt trường "chiều dài" trong một mảng Java sử dụng phản ánh

10 
10 
23 
Exception in thread "main" java.lang.NoSuchFieldException: length 
    at java.lang.Class.getField(Class.java:1520) 
    at Test.main(Test.java:9) 

Tại sao tôi không thể truy cập trường "chiều dài" trong mảng?

Trả lời

3

Tôi nghĩ đây có thể là lỗi trong triển khai JVM. Đây là lập luận của tôi:

  1. Theo the documentation for Class.getField, getField nên, như một phần (1) của thuật toán tìm kiếm của mình, tìm length nếu nó được khai báo là một lĩnh vực công cộng: "Nếu C tuyên bố một lĩnh vực nào với tên được chỉ định, đó là trường được phản ánh. "

  2. Theo the Java Language Specification, mỗi mảng có length được khai báo là "Độ dài trường cuối cùng công khai, chứa số thành phần của mảng".

  3. Kể từ lĩnh vực này được khai báo là có tên length, getField hoặc nên ném một SecurityException như tài liệu, hoặc nên trả lại đối tượng Field.

Bây giờ thú vị, phương pháp Class.getFields đề cập rõ ràng rằng "Các lĩnh vực chiều dài tiềm ẩn cho lớp mảng là không được phản ánh bằng phương pháp này. Mã người dùng nên sử dụng các phương pháp của lớp Array để thao tác mảng." Điều này dường như không song song với getField, vì vậy điều này có thể là một sự hiểu sai về phần của tôi hoặc tài liệu không tốt.

Hy vọng điều này sẽ hữu ích!

+0

Nó cũng có thể là một lỗi trong JLS;) Nhưng nó chắc chắn là lạ. – brimborium

8

Có lớp đặc biệt java.lang.reflect.Array. length không phải là trường thông thường. Để truy cập nó có một phương pháp đặc biệt getLength.

+0

Trong khi điều này cho phép phản ánh hoạt động chính xác, tôi nghĩ điều này không trả lời được câu hỏi. Câu hỏi của OP, ít nhất là khi tôi đọc nó, là lý do tại sao mã trên không thành công. – templatetypedef

+2

@templatetypedef nó thực sự làm. Ông nói rằng 'chiều dài' không phải là trường bình thường, giải thích' java.lang.NoSuchFieldException' ... – brimborium

+0

@ brimborium- Có một trích dẫn nào về lý do tại sao 'length' là" không có trường bình thường? " Theo các kiểu mảng JLS hoạt động như thể 'length' được khai báo là một trường công khai, và mặc dù bytecode khác với tra cứu trường, tôi không thể tìm thấy bất cứ điều gì đặc biệt nói rằng" chiều dài mảng là khác nhau ". – templatetypedef

0

Trong Java, mảng chỉ là các đối tượng đơn giản. Đối tượng không có bất kỳ trường nào có tên là chiều dài. Đó là lý do tại sao sự phản chiếu không thành công.

Vui lòng xem http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html để biết thêm thông tin về cách triển khai mảng.

Từ các tài liệu ...

chiều dài của một mảng không phải là một phần của loại của nó.

Các vấn đề liên quan