11

リフレクションをしているときに面白いものを見つけました。単純なクラスのコンストラクターとその修飾子を取得しようとしました。

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

コンストラクター修飾子を取得するコードは次のとおりです。

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)));
    }
}

結果は次のとおりです。

    public transient  

変数パラメーターではなく、配列だけをコンストラクターに渡せば問題ありません。

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

結果は次のとおりです。

    public  

コンストラクターの修飾子 (public、protected、private) またはパラメーターの型 (プリミティブまたは参照) に関係なく、同じことが起こります。「一時的」はコンストラクターの有効な修飾子ではありませんが、どうすればよいでしょうか?

4

1 に答える 1

17

アクセス修飾子は、クラス ファイル内でビット マスクとしてエンコードされます。JVM 仕様では、ビットがメソッド修飾子またはフィールド修飾子のどちらに現れるかに応じて、一部のビットに異なる意味を割り当てます。ビット 7 ( 0x0080) はそのようなビットの 1 つです。

メソッドの場合:

ACC_VARARGS    0x0080  Declared with variable number of arguments.

フィールドの場合:

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

メソッドを見ているので、この修飾子の正しい解釈はACC_VARARGSand notACC_TRANSIENTです。

ただし、このModifierクラスは、JVM 仕様で定義された修飾子のサブセットを処理できるようにしか見えません。必要なのは だけなので、区別することはできintません。ACC_VARARGSACC_TRANSIENT

于 2013-01-05T10:11:54.663 に答える