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

上記のコードを実行すると、コマンドラインで次の結果が得られます-

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)

配列の「長さ」フィールドにアクセスできないのはなぜですか?

4

3 に答える 3

10

特別なjava.lang.reflect.Arrayクラスがあります。length通常のフィールドではありません。これにアクセスするには、特別な方法がありgetLengthます。

于 2012-06-19T09:01:52.573 に答える
5

これはJVM実装のバグかもしれないと思います。これが私の推論です:

  1. のドキュメントにClass.getFieldよるとgetField、検索アルゴリズムの(1)の一部として、lengthパブリックフィールドとして宣言されているかどうかを確認する必要があります。「Cが指定された名前のパブリックフィールドを宣言した場合、それが反映されるフィールドです。」

  2. Java言語仕様によると、すべての配列はlength「配列のコンポーネントの数を含むパブリック最終フィールド長」として宣言されています。

  3. このフィールドは名前を持つと宣言されているため、文書化されたとおりlengthgetFieldをスローするか、オブジェクトSecurityExceptionを返す必要があります。Field

ここで興味深いことに、このClass.getFieldsメソッドは「配列クラスの暗黙の長さフィールドはこのメソッドに反映されません。ユーザーコードは配列を操作するためにクラスArrayのメソッドを使用する必要があります」と明示的に言及しています。これは並行しているようには見えないgetFieldので、これは私の側の誤読か、単に悪いドキュメントのいずれかである可能性があります。

お役に立てれば!

于 2012-06-19T09:09:52.310 に答える
0

Javaでは、配列は単なるオブジェクトです。オブジェクトには、 lengthというフィールドはありません。そのため、リフレクションは失敗しています。

アレイの実装方法の詳細については、 http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.htmlを参照してください。

ドキュメントから..。

配列の長さはその型の一部ではありません。

于 2012-06-19T13:52:28.760 に答える