2010-02-23 9 views
7

Ho bisogno di sapere quali array multidimensionali di classe in Java si estendono esattamente?Gli array multidimensionali in Java ampliano quale classe?

Quando si assegna

Object[] ref=new int[]{1,2,3}; 

il compilatore si lamenta che gli oggetti sono di diversi tipi. Quindi sembra che gli array monodimensionali si estendano a Object; Lo so già.

Ma quando assegniamo

Object[] ref2=new int[][]{{1,2,3},{4,5,6}}; 

il compilatore non si lamenterà. Quindi sembra che gli array bidimensionali si estendano Object[].

Ma quando stampo il suo nome superclasse:

System.out.println(ref2.getClass().getSuperclass().getName()); 

ho ottenuto java.lang.Object.

Quindi qualcuno può spiegare cosa sta succedendo qui?

risposta

13

Un array multidimensionale in Java è in realtà solo una matrice di matrici (di matrici) *.

Inoltre, gli array sono considerati sottoclassi di Object.

Così, il vostro è un int[][]Object[] (con tipo di componente int[]), ed anche un Object (perché tutti gli array sono oggetti)

Un int[], tuttavia, non è un Object[] (ma è ancora un Object).

così sembra che due array bidimensionali si estendono Object []

Io non sono sicuro se "estendere" è la parola giusta qui. Gli array hanno un posto speciale nel sistema di tipi Java e funzionano in modo leggermente diverso dagli altri oggetti. Un array bidimensionale è sicuramente un oggetto []. Ma se stai chiedendo delle superclassi, l'unica superclasse che ogni tipo di array ha è Object. Tutti gli array sono anche Clonabili e Serializable.

+1

Meglio formulata che la mia risposta. +1 –

+0

@mmyers: +1 per rimuovere la tua risposta in favore di upvoting di quello che pensavi fosse migliore (o buono e prima). Vorrei che più di noi l'avessero fatto! –

+0

Se continuiamo int [] [] [] è un oggetto [] [], quindi è una caratteristica gentile nel linguaggio java e non esiste una gerarchia di classi per questi array. – skystar7

3

Il tuo albero di ereditarietà sembra qualcosa di simile:

  1. RIF2 is-aint[][]
  2. RIF2 è-unObject[]
  3. RIF2 è-unObject

Ecco un codice frammento che illustra quello che voglio dire:

Object ref2 = new int[][]{{1,2,3}, {4,5,6}}; 
System.err.println("ref2: " + (ref2 instanceof int[][]) + 
    " " + (ref2 instanceof Object[])); 

Si dovrebbe vedere qualcosa di simile:

ref2: true true 
2

array in Java sono covarianti. Ciò significa che TSub[] è un sottotipo di TSuper[] se TSub è un sottotipo di TSuper.

Hai int[][] che è un array di int[]. Ora, come altri hanno sottolineato, qualsiasi array in Java è un sottotipo di Object, quindi int[] è un sottotipo di Object. Quindi, a causa della covarianza dell'array, int[][] è un sottotipo di Object[] (sostituto TSub = int[] e TSuper = Object nella precedente definizione di covarianza).

Modifica - Per rendere più chiaro il motivo di covarianza è importante, considerare che facendo la stessa cosa con List<T> non avrebbe funzionato:

List<Object> ref2 = new List<int[]>() 
+0

-1 la tua spiegazione è confusa - 'int' non eredita direttamente da' Object' – thecoop

+0

Non ho detto che lo ha fatto - int [] (array di int) fa. –

1

Quando si assegna

Object[] ref=new int[]{1,2,3}; 

il compilatore si lamenta

Questo perché int non è un sottotipo di Object, int.class.getSuperclass() restituisce null. Ricorda che in Java i valori primitivi (int, long, double, ...) non sono oggetti.

Quindi sembra che gli array bidimensionali estendano Object [].
Ma quando stampo il suo nome superclasse:

System.out.println(ref2.getClass().getSuperclass().getName()); 

ho ottenuto java.lang.Object.

Gli array sono più come interfacce, come fanno l'ereditarietà multipla. Ma non sono interfacce reali, nel senso di un'interfaccia Java.

class A {} 
interface I {} 
class B extends A implements I {} 


B[][] bArray = new B[1][1]; 
System.out.println(bArray instanceof A[][]); 
System.out.println(bArray instanceof I[][]); 
System.out.println(bArray instanceof Object[]); 
System.out.println(bArray.getClass().getSuperclass()); 
for (Class i: bArray.getClass().getInterfaces()) 
    System.out.println(i); 
System.out.println(I[][].class.isAssignableFrom(bArray.getClass())); 
System.out.println(I[][].class.isInstance(bArray)); 

uscita:

true 
true 
true 
class java.lang.Object 
interface java.lang.Cloneable 
interface java.io.Serializable 
true 
true 

Inoltre, Java viola il principio di sostituzione Liskov, perché

B[] bArray = new B[1]; 
A[] aArray = bArray; 
// bArray[0] = new A(); // causes a compile error 
aArray[0] = new A(); // compiles, but causes runtime exception 
Problemi correlati