2013-01-05 12 views
11

Znalazłem interesującą rzecz podczas pracy z refleksją. Próbowałem pobrać konstruktory prostej klasy i ich modyfikatory.Nieoczekiwany "przejściowy" modyfikator konstruktora

public class Test { 
    public Test(Object... args) {} 
} 

Oto kod, aby pobrać modyfikatory Konstruktor:

Class<?> clazz = Test.class; 
Constructor<?>[] ctors = clazz.getDeclaredConstructors(); 
for (Constructor<?> ctor : ctors) {   
    int mod = ctor.getModifiers(); 
    /*if not package-private modifier*/ 
    if(mod!=0) { 
     System.out.println(Modifier.toString(mod))); 
    } 
} 

Wynikiem jest:

public transient 

Gdybym przekazać do konstruktora nie zmiennych parametrów, ale tylko tablica, to w porządku.

public class Test { 
    public Test(Object[] args) {} 
} 

Wynikiem jest:

public 

To samo dzieje się niezależnie z konstruktora modyfikatora (publiczne, chronione prywatny) lub parametrów typu (pierwotne lub odniesienie). Jak to możliwe, podczas gdy "przejściowy" nie jest poprawnym modyfikatorem dla konstruktora?

Odpowiedz

17

Modyfikatory dostępu są zakodowane jako maski bitów w pliku klasy. Specyfikacja JVM przypisuje różne znaczenie niektórym bitom w zależności od tego, czy pojawiają się one w modyfikatorze metody czy modyfikatorze pola. Bit 7 (0x0080) jest jednym z takich bitów.

For methods:

ACC_VARARGS 0x0080 Declared with variable number of arguments. 

For fields:

ACC_TRANSIENT 0x0080 Declared transient; not written or read by a persistent 
         object manager. 

Skoro jesteś patrząc na sposób, prawidłowa interpretacja tego modyfikatora jest ACC_VARARGS i nie ACC_TRANSIENT.

Jednak klasa Modifier wydaje się być w stanie poradzić sobie z podzestawem modyfikatorów zdefiniowanych w specyfikacji JVM. Ponieważ wszystko, czego potrzeba, to int, nie można odróżnić ACC_VARARGS i ACC_TRANSIENT.

+1

Czy to się liczy jako błąd metody 'toString'? –

+1

@JanDvorak: Nie jestem pewien. W obecnej sytuacji wydaje się, że klasa "Modifier" jest w stanie poradzić sobie z podzestawem modyfikatorów zdefiniowanych w specyfikacji JVM (ponieważ nie jest w stanie odróżnić modyfikatorów o tej samej wartości bitowej). – NPE

+1

Zastanawiam się - dlaczego wartości bitów rzeczywiście zderzają się? Czy to nie jest niedopatrzenie od twórców JVM? –

Powiązane problemy