2012-06-19 11 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; 
}; 

Kiedy uruchomić powyższy kod, pojawia się następujący wynik z linii poleceń -Pierwsze pole „długość” w tablicy Java przy użyciu odbicia

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) 

Dlaczego nie jestem w stanie uzyskać dostęp pole "długość" w tablicy?

Odpowiedz

3

Myślę, że to może być błąd w implementacji JVM. Oto moje rozumowanie:

  1. Według the documentation for Class.getField, getField powinny, w ramach (1) swojego algorytmu wyszukiwania, znajdź length gdyby został uznany jako pole publicznym: „Jeśli C deklaruje pole publicznego z nazwą określone, to pole do odzwierciedlenia. "

  2. Zgodnie z the Java Language Specification każda tablica ma length zadeklarowaną jako "Publiczna długość pola końcowego, która zawiera liczbę składników tablicy."

  3. Ponieważ pole jest zadeklarowane jako posiadające nazwę length, getField powinien albo rzucić SecurityException jako udokumentowane, czy powinien wrócić obiekt Field.

Teraz ciekawe, metoda Class.getFields wyraźnie wspomina, że ​​„długość ukryte pole do klasy tablicy nie odbija się tą metodą. Kod użytkownika należy użyć metod klasy Array manipulować tablic.” Nie wydaje się to być równoznaczne z getField, więc może to być błędne odczytanie z mojej strony lub po prostu zła dokumentacja.

Mam nadzieję, że to pomoże!

+0

Może to być również błąd w JLS;) Ale jest to zdecydowanie dziwne. – brimborium

8

Istnieje specjalna klasa java.lang.reflect.Array. length nie jest normalnym polem. Aby uzyskać do niego dostęp, istnieje specjalna metoda getLength.

+0

Chociaż pozwala to na prawidłowe działanie odbicia, myślę, że to nie odpowiada na pytanie. Pytanie OP, przynajmniej tak, jak je czytam, brzmi, dlaczego powyższy kod zawodzi. – templatetypedef

+2

@templatetypedef to faktycznie robi. Mówi, że "długość" nie jest normalnym polem, co tłumaczy 'java.lang.NoSuchFieldException' ... – brimborium

+0

@ brimborium- Czy istnieje wzmianka o tym, dlaczego" długość "to" brak normalnego pola? " Według typów tablic JLS działa tak, jakby "długość" została zadeklarowana jako pole publiczne i chociaż kod bajtowy jest inny dla wyszukiwania pól, nie mogę znaleźć niczego konkretnego mówiącego "długość tablicy jest inna". – templatetypedef

0

W Javie tablice są po prostu zwykłymi obiektami. Obiekt nie ma żadnego pola o nazwie o długości. Właśnie dlatego odbicie się nie udaje.

Aby uzyskać więcej informacji na temat implementacji tablic, zobacz artykuł http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html.

Z dokumentacji ...

długość tablicy nie jest częścią jego typu.

Powiązane problemy