问题 使用反射在Java数组中获取字段“length”


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)

为什么我无法访问数组中的“长度”字段?


5905
2018-06-19 08:56


起源



答案:


我认为这可能是JVM实现中的一个错误。这是我的推理:

  1. 根据 的文件 Class.getFieldgetField 应该,作为其搜索算法的第(1)部分,找到 length 如果它被声明为公共字段:“如果C声明一个指定名称的公共字段,那就是要反映的字段。”

  2. 根据 Java语言规范,每个阵列都有 length 声明为“公共最终字段长度,其中包含数组的组件数”。

  3. 由于此字段被声明为具有名称 lengthgetField 应该扔一个 SecurityException 如记录,或应返回 Field 目的。

现在有趣的是, Class.getFields 方法明确提到“此方法不反映数组类的隐式长度字段。用户代码应使用类Array的方法来操作数组。”这似乎并不平行 getField,所以这可能是我的误读或只是糟糕的文档。

希望这可以帮助!


3
2018-06-19 09:09



它也可能是JLS中的一个错误;)但它确实很奇怪。 - brimborium


答案:


我认为这可能是JVM实现中的一个错误。这是我的推理:

  1. 根据 的文件 Class.getFieldgetField 应该,作为其搜索算法的第(1)部分,找到 length 如果它被声明为公共字段:“如果C声明一个指定名称的公共字段,那就是要反映的字段。”

  2. 根据 Java语言规范,每个阵列都有 length 声明为“公共最终字段长度,其中包含数组的组件数”。

  3. 由于此字段被声明为具有名称 lengthgetField 应该扔一个 SecurityException 如记录,或应返回 Field 目的。

现在有趣的是, Class.getFields 方法明确提到“此方法不反映数组类的隐式长度字段。用户代码应使用类Array的方法来操作数组。”这似乎并不平行 getField,所以这可能是我的误读或只是糟糕的文档。

希望这可以帮助!


3
2018-06-19 09:09



它也可能是JLS中的一个错误;)但它确实很奇怪。 - brimborium


有一个特别的 java.lang.reflect.Array 类。 length 不是正常的领域。要访问它,有一种特殊的方法 getLength


9
2018-06-19 09:01



虽然这确实允许反射正常工作,但我认为这不能回答这个问题。 OP的问题,至少在我阅读时,是上述代码失败的原因。 - templatetypedef
它实际上是@templatetypedef。他说 length 不是正常的领域,这解释了 java.lang.NoSuchFieldException... - brimborium
@ brimborium-是否有引用的原因 length 是“没有正常的领域?”根据JLS数组类型表现得好像 length 被声明为公共字段,尽管字段代码对于字段查找是不同的,但我找不到任何具体说“数组长度不同”的内容。 - templatetypedef
brimborium的答案链接到SO线程,为此提供了一些引用。 - Maccesch


在Java中,数组只是简单的对象。对象没有任何调用的字段 长度。这就是反思失败的原因。

请参见 http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html 有关如何实现数组的更多信息。

从文档......

数组的长度不属于其类型。


0
2018-06-19 13:52