saber que originales mejor medicamentos medicamento listado genericos generico cual como comercial bioequivalencia java generics wildcard

java - que - ¿Cuál es el propósito de los comodines y en qué se diferencian de los genéricos?



medicamentos originales y genericos (4)

La diferencia entre sus 2 ejemplos es simplemente que el primero es una lista de animales genéricos / generales; por lo tanto, puede agregarle cualquier tipo de animal y cualquier instancia de una subclase de tipo Animal. (por ejemplo, puede contener algunos perros, algunos gatos, algunos puercoespines ...) Mientras que el segundo: ¿ List <? extends Animal> List <? extends Animal> - será una lista de un subtipo específico de animal de clase. Puede ser cualquiera que elija (esto se establece cada vez en tiempo de ejecución), pero solo uno. Será una lista de perros, o una lista de gatos, o una lista de tortugas ... etc.

Nunca había oído hablar de los coches salvajes hasta hace unos días y, después de leer el libro de Java de mi profesor, todavía no estoy seguro de para qué sirve y por qué tendría que usarlo.

Digamos que tengo una súper clase Animal y algunas subclases como Dog , Cat , Parrot , etc ... Ahora necesito tener una lista de animales, mi primer pensamiento sería algo como:

List<Animal> listAnimals

En cambio, mis colegas están recomendando algo como:

List<? extends Animal> listAnimals

¿Por qué debería usar comodines en lugar de genéricos simples?

Digamos que necesito tener un método get / set, ¿debo usar el primero o el posterior? ¿Cómo son tan diferentes?


Los comodines no tienen mucho sentido al declarar variables locales, sin embargo, son realmente importantes al declarar un parámetro para un método.

Imagina que tienes un método:

int countLegs ( List< ? extends Animal > animals ) { int retVal = 0; for ( Animal cur : animals ) { retVal += cur.countLegs( ); } return retVal; }

Con esta firma puedes hacer esto:

List<Dog> dogs = ...; countLegs( dogs ); List<Cat> cats = ...; countLegs( cats ); List<Animal> zoo = ...; countLegs( zoo );

Sin embargo, si declara countLegs así:

int countLegs ( List< Animal > animals )

Luego, en el ejemplo anterior, solo countLegs( zoo ) se habría compilado, porque solo esa llamada tiene un tipo correcto.


Los genéricos de Java son invariantes.

Supongamos que tenemos B extends A :

  • B es un subtipo de A
  • una instanceof B es también una instanceof A

Dado que los arreglos de Java son covariantes:

  • B[] es un subtipo de A[]
  • una instanceof B[] es también una instanceof A[]

Sin embargo, los genéricos de Java son invariantes:

  • List<B> NO es un subtipo de List<A>
  • una instanceof List<B> NO es una instanceof List<A> .

Los comodines se utilizan para hacerlo más flexible al tiempo que se preserva la seguridad del tipo.

  • una List<B> es una List<? extends A> List<? extends A>

Referencias

Preguntas relacionadas


Puede almacenar perros y gatos en una List<Animal> . No es allí donde se necesitan comodines.

Digamos que tienes un método que toma una lista de animales:

void foo(List<Animal> animals) { ... }

Ahora no puede pasar el método a List of Dogs, solo toma un argumento de tipo List<Animal> . Necesita un comodín para que el método acepte todo tipo de listas de animales: List<Animal> , List<Dog> , List<Cat> , ...

void foo(List<? extends Animal> animals) { ... }

Ver

http://java.sun.com/docs/books/tutorial/extra/generics/wildcards.html