Diga A
es una interfaz. ¿Cuál es la diferencia entreDiferencia entre <T extends A> void foo (T t) y void foo (A a)
public <T extends A> void foo(T t) { ... }
y
public void foo(A a) { ...}
?
Diga A
es una interfaz. ¿Cuál es la diferencia entreDiferencia entre <T extends A> void foo (T t) y void foo (A a)
public <T extends A> void foo(T t) { ... }
y
public void foo(A a) { ...}
?
No mucho.
Por otro lado, considere este método:
public <T extends A> T transform(T t);
Y el código de llamada:
class B implements A { ... }
B result = transform(new B(...));
No sería posible (arriba no compilar, como compilador que obligaría a declarar result
tipo que A
) tuvo que declaró como método
public A transform(A a)
No hay diferencia cuando se utiliza un objeto. Pero imagínese si usted tenía
class B extends A { ... }
y
public void f(List<A> list) { ... };
y
public <T extends A> void f(List<T> list) { ... };
con el primero se puede pasar una lista que es exactamente el tipo de List<A>
. Con el segundo, puede pasar una lista que contiene objetos que extienden A
. Sin embargo, con el primero no puedes hacer lo mismo. En otras palabras, no se pudo pasar List<B>
al primer método, pero se pudo pasar al segundo método.
para el segundo caso aún puede escribir 'public void f (Lista extends A> list);' – newacct
Sí, puede. Solo estaba mostrando un ejemplo. –
No hay diferencia en su caso porque el parámetro de tipo se usa en un solo lugar. Ambos métodos aceptan cualquier cosa que es una A o extiende A. El método genérico tendría más sentido en este caso porque el parámetro de tipo le permiten atar el valor de retorno para el parámetro pasado:
public <T extends A> T f(Class<T>) {...}
Tanto si se hace una diferencia depende de lo que hay dentro de esa función.
El objetivo de los genéricos es garantizar la seguridad del tipo. Supongamos que A tiene dos subclases, llamémoslas B y C. En el primer ejemplo, usando f (Lista < A>), la lista podría incluir B, C o una mezcla de ambas. Pero en el segundo ejemplo, f < T se extiende A> (Lista < T>), cuando invocamos la función debemos especificar el tipo. Si decimos f < B>, entonces sabemos que esta es una lista de B, no se permiten las C. No podremos pasar una lista de C o A's genéricos, no podemos agregar C a la lista, y cualquier cosa que saquemos será un B.
Si esto es bueno o malo depende de lo que estás tratando de hacer Si la idea es que desea una lista que sea B o C, el genérico ayuda a garantizar esto. Si desea una lista que puede ser una mezcla de los dos, entonces no desea usar el genérico, use la simple f (Lista < A>).
¿A qué ejemplos se refiere? – newacct
Por "ejemplos" me refiero a las dos declaraciones de funciones que dio el póster original: el "
No veo eso en la pregunta; solo en una de las respuestas – newacct
Esto también es cierto si tiene un tipo de devolución. –
"si declaras f como", ¿qué significa la 'f'? – Freewind
@Freewind gracias, corregido error tipográfico. –