2012-10-06 103 views
15
public class RefMix { 
    public static void main(String[] args) { 
    Object[] a = {null, "foo"}; 
    Object[] b = {"bar", b}; 
    a[0] = b; 

    System.out.println(a[0][0]); 
    } 
} 

Tengo entendido que las matrices son objetos en Java y, por lo tanto, una subclase del tipo de objeto. Mi entendimiento adicional es que una matriz de 2 dim se implementa como una matriz de referencias a matrices. Por lo tanto, no entiendo por qué mi a [0] [0] no produce bar en el código anterior. En su lugar, no se compila:Tipo de objeto en Java y matrices de referencia

RefMix.java:7: array required, but java.lang.Object found 

Respuesta

13

Mi comprensión es que las matrices son objetos en Java y, por lo tanto, una subclase del tipo de objeto. Mi entendimiento adicional es que una matriz de 2 dim se implementa como una matriz de referencias a matrices.

Todo esto es correcto y explica por qué se puede hacer la tarea

a[0] = b; 

sin ninguna queja de que el compilador.

Por lo tanto, no entiendo por qué mi a [0] [0] no produce la barra en el código anterior.

Está bien, vamos a echar un vistazo a los tipos en esta expresión:

  • a es una Object[] - que es un conjunto de Object s
  • a[0] es un Object
  • a[0][0] - - Ahora intenta usar un subíndice de matriz en un Object. El compilador no sabe que el Object es de hecho una matriz, por lo que se queja.
10

El tipo de tiempo de ejecución de una instancia de objeto difiere del tipo estáticamente inferido. El compilador intentará estimar qué tipo de cada variable podría estar en el programa, con el fin de detectar ciertos tipos de errores temprano. En este caso, a[0] siempre será una matriz, pero el compilador no lo sabe. Como obtiene un objeto de una matriz de objetos, todo lo que sabe el compilador es que a[0] es un objeto. Por lo tanto, genera un error.

En los casos en que sabe que algo siempre será de un tipo determinado pero el compilador no puede resolverlo, puede solucionarlo insertando un molde explícito.

System.out.println(((Object[])a[0])[0]); 
+0

La fealdad de un elenco como este me ha inspirado a abandonar el uso de matrices como esta; Usaré una clase "normal" de referencias a objetos. ¡Pero gracias! – Fixee

+3

@Fixee, las matrices en Java son bastante feas, pero a menudo puede evitar la necesidad de conversiones reduciendo la cantidad de veces que almacena datos heterogéneos. Normalmente no necesita almacenar ambas cadenas y object [] s en la misma matriz. – Antimony

+2

@Antimony En realidad, no puedo encontrar un solo caso de uso donde * necesitarías * tal cosa ...;) – brimborium

4

Desde array en Java es un objeto, por lo que la primera y la segunda asignación, almacenará la matriz como el primero elemento de su matriz de objeto ..

Object[] a = {null, "foo"}; 
Object[] b = {"bar", b}; 

Ahora, usted ha cambiado su primera elemento de a matriz de objetos para contener el valor b en lugar de la matriz ... Pero como se trata de una matriz de objetos. Todo lo que sale de ella será objeto ..

Desde un [0] es un objeto .. Por lo tanto, es lógico que no acceder a algo como esto: -

System.out.println(a[0][0]); 

se puede tratar de encasillar el objeto a [0] a tabla de objetos ..: -

System.out.println(((Object[])a[0])[0]); 
4

Do:

System.out.println(((Object[])a[0])[0]); 

Este "lanzará" el objeto a una matriz de objetos en tiempo de ejecución.

7

tiene usted razón, las matrices son siempre Objects en Java, pero no siempre son Objects matrices, por lo tanto, se obtiene un error de compilación, porque es un aObject[] (unidimensional). No se puede acceder a

a[0][0]; 

porque a no es una matriz de dos dimensiones (por lo menos no es declarado como tal). Sin embargo, en este caso, está seguro de que a[0] es una matriz de Objects. Por lo tanto, usted puede hacer esto:

Object[] c = (Object[]) a[0]; 
System.out.println(c[0]); 
// or directly: 
System.out.println(((Object[])a[0])[0]); 

Esto arroja el tipo de retorno de a[0] (que es Object), en un Object[] y luego se puede acceder a la "segunda capa" de la matriz.

1

Todo lo que usted está haciendo es equivalente a este

Object a = {"bar", "foo"}; 
System.out.println(a[0]); 

que no sea compilar.

2

Como hago últimamente mucha codificación en C++, me parece que Java es mucho más estricto en el control de tipos que C++. Java lo ve todo menos los tipos primitivos como Object, pero Java va un paso más allá en la distinción de los tipos Array y non Array. Durante la asignación como "a [0] = b;" Primero, java comprueba si es un tipo de matriz o no, después de eso pasa a través del procedimiento de comprobación de tipo polimórfico regular. Si desea hacer su trabajo de código, que debe hacer ...

Object[][] a = {{null}, {"foo"}}; 
Object[] b = {"bar", new java.util.Date()}; 
a[0] = b; 

Se puede ver cómo java tener especial cuidado en los tipos de matriz mirando en Java Class firma que se pasa a Class.forName() como parámetro . Por ejemplo, el tipo de datos ..

com.foo.Bar[][] barsIn2D; 

Se puede cargar con firma abajo ...

// [ => Array 
// [[ => Array of Array type 
// L<object>; => Object, not Array 
Class.forName("[[Lcom/foo/Bar;"); 

Como se ve, la firma comienza ya sea con '[' o 'L'. Esto nos dice si su matriz o no tiene prioridad sobre "Lcom/foo/Bar;".

Cuestiones relacionadas