2011-01-23 17 views
10

En Java, ¿por qué una matriz no puede ser una variable de tipo vinculada, pero puede ser un comodín vinculado?En Java, ¿por qué una matriz no puede ser una variable de tipo vinculada, pero puede ser un comodín vinculado?

Puede tener:

List< ? extends Integer[] > l; 

pero no se puede tener:

class MyClass< T extends Integer[] > { } // ERROR! 

¿Por qué?

+0

Es extraño. El JLS establece claramente que solo puede usar clases o interfaces en las variables de tipo pero no proporciona ninguna explicación. – biziclop

+0

solo para hacer "like-comparisons": "List k1;" está permitido, pero "List k2;" no es. ¡Pero no pude encontrar nada excepto null para agregar a la lista! Eclipse dice que k1.get (0) devuelve tipo Integer [], pero no pude agregar uno. –

Respuesta

7

Considere este código Java:

package test; 

public class Genric<E> 
{ 
    public Genric(E c){ 
     System.out.println(c.getClass().getName()); 
    } 
    public static void main(String[] args) { 
     new Genric<Integer[]>(new Integer[]{1,2}); 
    } 
} 

Para su primer caso:

List< ? extends Integer[] > l; 

Cuando haces algo como esto List< ? extends Integer[] > l; entonces el compilador de Java lo ve como una List< ? extends Object> l; y lo traduce en consecuencia . Entonces esta es la razón por la cual no obtienes ningún error.

El byte-código generado es el siguiente:

. 
    . 
    . 
    20: aastore 
    21: invokespecial #52; //Method "<init>":(Ljava/lang/Object;)V 
    24: return 
    . 
    . 

Pedido el número de línea . Aunque, he pasado una matriz de java.lang.Integer; internamente se traduce al java.lang.Object.

Para su segundo caso:

class MyClass< T extends Integer[] > { } // ERROR! 

De acuerdo con la especificación del lenguaje Java:

TypeParameter: 
TypeVariable TypeBoundopt 

TypeBound: 
extends ClassOrInterfaceType AdditionalBoundListopt 
. 
. 

Como se puede ver el la cota consiste exclusivamente de clase o una interfaz (ni siquiera los tipos primitivos) Entonces cuando haces algo como esto class MyClass< T extends Integer[] > { } entonces Integer[] no califica como una clase o interfaz.

Según mi comprensión de Java Spec, esto se hizo para resolver todos los escenarios como

  1. class MyClass< T extends Integer[] >
  2. class MyClass< T extends Integer[][] >
  3. ..
  4. class MyClass< T extends Integer[][]...[] >

Debido a que todos ellos pueden ser representados como java.lang.Object y cuando pasan como parámetro, como en el ejemplo

public Genric(E c){ 
      System.out.println(c.getClass().getName()); 
     } 

como 'c' recuerda su tipo verdadero.

Espero que esto ayude.

+0

+1 para profundizar en el código byte, aunque esto todavía es más como una explicación de "cómo" en lugar de "por qué". ¿No es la sustitución del parámetro tipo por 'Objeto' simplemente debido a borrado de tipo , y aplicado siempre? Es decir 'List ' también se convertiría en una 'Lista 'en el bytecode, ¿verdad? La seguridad de tipo genérico es verificada solo por el compilador antes de que ocurra el borrado de tipo. –

0

Usted puede hacer algo como:

public class MyClass<K> { 
    K array; 
    public MyClass(K k) { 
     array = k; 
    } 

O usted podría hacer algo como esto:

class MyClass< T extends Integer > { 
    ...make your variable MyClass[]... 
} 

Espero que esto ayude y no estoy demasiado lejos de lo que estaba pidiendo.

+0

Creo que pregunta "POR QUÉ" no "CÓMO ..." :( – Xorty

+0

De hecho, no estoy tratando de usar una matriz como un límite para T. Solo quería saber por qué se impone esta restricción. –

+0

Disculpe por la malentendido, si me dices cómo eliminar esta publicación me desharé de ella, ya que es irrelevante. – 4everAStudent

3

Estoy tratando de pensar en razones específicas esto debe ser prohibido, pero el único que se me ocurre es que es una construcción completamente innecesario, porque:

class Foo<T extends Integer[]> { 
    T bar(); 
} 

es equivalente a

class Foo<T extends Integer> { 
    T[] bar(); 
} 

Obviamente, no se puede decir lo mismo sobre el caso del comodín, por lo tanto, está permitido allí.

Cuestiones relacionadas