2012-01-11 3 views
7

Creo que me falta algo básico aquí. Cualquier explicación o sugerencia a preguntas previamente hechas será muy útil.¿Hay una subclase de matriz String de una matriz de objetos?

import java.util.Arrays; 
import java.util.List; 

public class St { 

    public static void bla(Object[] gaga) { 
      gaga[0] = new Date(); // throws ArrayStoreException 
     System.out.println(gaga[0]); 
    } 

    public static void bla(List<Object> gaga) { 
     System.out.println(gaga.get(0)); 
    } 

    public static void main(String[] args) { 
      String[] nana = { "bla" }; 
     bla(nana); // Works fine 

     List<String> bla1 = Arrays.asList(args); 
     bla(bla1); // Wont compile 

      System.out.println(new String[0] instanceof Object[]); // prints true 
      System.out.println(nana.getClass().getSuperclass().getSimpleName()); // prints Object 
    } 

} 

Por lo tanto, parece que una List<String> no es una subclase de un List<Object> sino un String[] es una subclase de Object[].

¿Es esto una suposición válida? Si es así, ¿por qué? Si no, ¿por qué?

Gracias

Respuesta

10

Java arrays are covariant, es decir, que permiten Object[] foo = new String[2];. Pero esto no significa que sean subclases. String[] es una subclase de Object (aunque instanceof devoluciones, String[].class.getSuperclass() vuelve Object cierto)

+0

De @maerics comenta a continuación: la 'nueva instancia String [0] de Object []' devuelve verdadero. Entonces, String [] es un tipo de Objeto y un tipo de Objeto [] y un tipo de CharSequence [] etc. ¿Correcto? – Kal

+0

@Kal que parece ser un caso especial para cubrir la covarianza. Ver mi actualización – Bozho

+0

Gracias .. Acabo de ver su edición. – Kal

3
(new String[0] instanceof Object[]) // => true 
3

Estás en lo correcto. Los tipos de matriz son covariantes en Java por diseño, pero un Foo<Sub> no es un Foo<Super>.

5

Sí, su suposición es válida. Como dicen las matrices @Bozho son covariantes, mientras que las colecciones genéricas (como la Lista genérica) no son covariantes.

covarianza de matrices es arriesgado:

String[] strings = new String[] { "a", "b" } 
Object[] objects = strings; 
objects[0] = new Date(); // <-- Runtime error here 
String s = strings[0]; 
s.substring(5, 3);  // ????!! s is not a String 

La tercera línea dispara una excepción en tiempo de ejecución. Si no se activa esta excepción, puede obtener una variable String, s, que hace referencia a un valor que no es String (ni un subtipo del mismo): a Date.

+0

Gracias ... Nunca antes había visto ArrayStoreException. – Kal

2

String [] es una subclase de Object []

correcta, ver 4.10.3 Subtyping among Array Types:

Si S y T son ambos tipos de referencia, entonces S []> 1 T [ ] si y sólo si S> 1 T.

Desde String >1 Object así String[] >1 Object[]

Esto es, String[] es un subtipo directa de Object[]

Objeto> 1 Object []

para ello Object > String[]; String[] es un (indirecta?) subtipo de Object

No existe tal relación de los genéricos, por lo List<String> > List<Object> no es cierto.

Ahora, consideremos el siguiente ejemplo:

import java.util.*; 

class G { 
    interface I { 
    void f(); 
    } 
    class C implements I { 
    public void f() {} 
    } 

    void allF(List<I> li) { 
    for (I i : li) { i.f(); } 
    } 

    void x(List<C> lc) { 
    allF(lc); 
    } 
} 

No compila, porque x invoca allF con un List<C> que es no un List<I>. Para poder utilizar List<C> la firma tiene que cambiar un poco:

void allF(List<? extends I> li) { 

Ahora se compila. De manera informal, li es una List de algún tipo que se extiende/implementa I. Así List<C>es asignable aList<? extends I>. Lo que puedes hacer con tal lista es limitado. Básicamente, puede leer/acceder pero no puede write/modify.

+0

Umm ... subtipo y subclase significan cosas diferentes. –

+1

@StephenC, para la subtipificación de clases es lo mismo que la creación de subclases, si estoy leyendo [4.10.2] (http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls- 4.10.2). Supongo que la respuesta correcta sería "Las matrices no son clases, por lo que no pueden tener una relación de subclase, pero String [] * es * a * sybtype * de Object []". ¿Es eso lo que estás insinuando? –

Cuestiones relacionadas