2012-06-19 11 views
11
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; 
}; 

Cuando ejecuto el código anterior, me sale el siguiente resultado en la línea de comandos -Conseguir el campo "longitud" en una matriz de Java utilizando la reflexión

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) 

¿Cómo es que no soy capaz de Acceso el campo "longitud" en la matriz?

Respuesta

3

Creo que esto podría ser un error en la implementación de JVM. Aquí está mi razonamiento:

  1. Según the documentation for Class.getField, getField deberían, en la parte (1) de su algoritmo de búsqueda, encontrar length si se hubiera declarado como un campo público: "Si C declara un campo público con el nombre especificado, ese es el campo que se reflejará ".

  2. De acuerdo con the Java Language Specification, cada matriz tiene length declarada como "La longitud del campo final público, que contiene el número de componentes de la matriz".

  3. Desde este campo se declara como que tenían el nombre length, ya sea getField debe lanzar una SecurityException como se documenta, o debería devolver el objeto Field.

Ahora, curiosamente, el método Class.getFields menciona explícitamente que "El campo de longitud implícita para la clase de matriz no es reflejada por este método. El código de usuario debe utilizar los métodos de la clase Array para manipular matrices". Esto no parece ser paralelo al getField, por lo que podría ser una mala lectura por mi parte o simplemente una mala documentación.

Espero que esto ayude!

+0

También puede ser un error en el JLS;) Pero definitivamente es extraño. – brimborium

8

Hay una clase especial java.lang.reflect.Array. length no es un campo normal. Para acceder a él hay un método especial getLength.

+0

Si bien esto permite que la reflexión funcione correctamente, creo que esto no responde a la pregunta. La pregunta del OP, al menos mientras lo estoy leyendo, es por qué falla el código anterior. – templatetypedef

+2

@templatetypedef realmente lo hace. Él dice que 'length' no es un campo normal, lo que explica la 'java.lang.NoSuchFieldException' ... – brimborium

+0

@ brimborium- ¿Hay alguna cita para por qué' length' es "no field normal?" De acuerdo con los tipos de matriz JLS actúan como si 'length' fuera declarado como un campo público, y aunque el bytecode es diferente para las búsquedas de campo, no puedo encontrar nada específicamente que diga" la longitud de la matriz es diferente ". – templatetypedef

0

En Java, las matrices son simplemente objetos simples. El objeto no tiene ningún campo llamado longitud. Es por eso que la reflexión está fallando.

Consulte http://docs.oracle.com/javase/specs/jls/se7/html/jls-10.html para obtener más información sobre cómo se implementan las matrices.

De la documentación ...

longitud de una matriz no es parte de su tipo.

Cuestiones relacionadas