【问题标题】:Getting the field "length" in a Java array using reflection使用反射获取 Java 数组中的字段“长度”
【发布时间】:2012-06-19 08:56:41
【问题描述】:
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)

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

【问题讨论】:

    标签: java arrays reflection


    【解决方案1】:

    有一个特殊的java.lang.reflect.Array 类。 length 不是普通字段。要访问它,有一个特殊的方法getLength

    【讨论】:

    • 虽然这确实允许反射正常工作,但我认为这并不能回答问题。 OP 的问题,至少在我阅读时,是上述代码失败的原因。
    • @templatetypedef 确实如此。他说length 不是普通字段,这就解释了java.lang.NoSuchFieldException...
    • @brimborium- 有没有引用为什么length 是“没有正常字段?”根据 JLS 数组类型,就像 length 被声明为公共字段一样,尽管字段查找的字节码不同,但我找不到任何具体说明“数组长度不同”的内容。
    • 来自 brimborium 的答案链接到一个 SO 线程,该线程为此提供了一些引用。
    【解决方案2】:

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

    1. 根据the documentation for Class.getFieldgetField 应该作为其搜索算法的一部分(1),如果 length 被声明为公共字段:“如果 C 声明一个名为指定,即要反映的字段。”

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

    3. 由于该字段被声明为名称为 lengthgetField 应该按照文档中的说明抛出 SecurityException,或者应该返回 Field 对象。

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

    希望这会有所帮助!

    【讨论】:

    • 它也可能是 JLS 中的一个错误 ;) 但它绝对是奇怪的。
    【解决方案3】:

    在 Java 中,数组只是简单的对象。对象没有任何名为 length 的字段。这就是反射失败的原因。

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

    来自文档...

    数组的长度不是其类型的一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-08
      • 1970-01-01
      • 1970-01-01
      • 2013-02-25
      • 2019-04-09
      • 1970-01-01
      相关资源
      最近更新 更多