使用反射在Java数组中获取字段"length"

mat*_*ots 11 java arrays reflection

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;
};
Run Code Online (Sandbox Code Playgroud)

当我运行上面的代码时,我在命令行上得到以下结果 -

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)
Run Code Online (Sandbox Code Playgroud)

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

Mac*_*sch 10

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

  • 它实际上是@templatetypedef.他说`length`不是普通字段,这解释了`java.lang.NoSuchFieldException` ... (3认同)

tem*_*def 5

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

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

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

  3. 由于此字段被声明为具有 name length,因此getField应该SecurityException按照文档抛出 a ,或者应该返回Field对象。

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

希望这可以帮助!