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.getFieldgetField应该作为其搜索算法的一部分(1),查找length它是否被声明为公共字段:“如果 C 声明了一个具有指定名称的公共字段,那就是要反映的字段。”

  2. 根据Java Language Specification,每个数组都length声明为“公共最终字段长度,其中包含数组的组件数”。

  3. 由于该字段被声明为具有 name lengthgetField因此应该按照记录抛出 a 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 回答