wildcards type objects node generic example data bounded java generics inheritance

java - type - cuestión de genéricos y herencia



java generics bounded wildcards (4)

Cuando instancia un tipo genérico con diferentes argumentos de tipo, las dos instancias no son compatibles con el tipo. Las diferentes instancias de un tipo genérico no son de tipo equivalente en la forma en que una clase que hereda de otra clase es de tipo equivalente a esa clase, incluso cuando los propios argumentos de tipo pueden estar relacionados por herencia. Genericity y polimorfismo son dos características separadas del lenguaje.

Tu código es equivalente a lo siguiente:

// Java defaults unspecified type arguments to Object. fileHandler<Object, Object> file; if (...) { // Error: fileHandler<String, String> is not equivalent to fileHandler<Object, Object> file = new fileHandler<String, String>(); } else { // Error: fileHandler<String, String[]> is not equivalent to fileHandler<Object, Object> file = new fileHandler<String, String[]>(); }

Si realmente desea aislar una interfaz polimórfica que sea independiente de los tipos utilizados para crear una instancia de su clase fileHandler, le sugiero que utilice una interfaz:

interface IFileHandler { // If this interface needs to talk about keys and values, it // does so using only java.lang.Object. } public class fileHandler<Key extends Object, Value extends Object> implements IFileHandler { // ... } public class A extends fileHandler<String, String> { // ... } public class B extends fileHandler<String, String[]> { // ... } IFileHandler file; if (...) { file = new A(); } else { file = new B(); }

Tengo tres clases:

public abstract class fileHandler<Key extends Object, Value extends Object> { } public A extends fileHandler<String, String[]> { } public B extends fileHandler<String, String> { }

Ahora en mi función principal hago algo como esto:

fileHandler file= null; If (<condition>) { fileHandler = new A(); } else fileHandler = new B(): }

Pero esto da 2 errores de tiempo de compilación:

  1. No se puede convertir A en fileHandler
  2. No se puede convertir B en fileHandler

¿Cómo puedo deshacerme de estos errores ya que no obtengo este error si la clase base no es genérica?

Actualizar:

Mi jerarquía de clase es:

  1. class fileHandler<Key, Value> { }
  2. class A extends fileHandler<String, String[]> { }
  3. class B extends fileHandler<String, String> { }
  4. clase C que llama a la función gen(object of A) o
  5. clase D que llama a la función gen(object of B) .
  6. tanto C como D se derivan de la clase abstracta E.

Ahora, ¿cómo debería definir estas funciones en C, D y E?

Di lo siguiente:

MI:

public abstract void gen (fileHandler A) throws exception;

DO:

void gen (fileHandler A) throws exception;

RE:

void gen (fileHandler A) throws exception;

C, D y E dan error fileHandler es tipo raw. Se debe parametrizar la referencia al tipo genérico fileHandler (Key, Value).


El problema es que estás tratando de asignar una instancia al nombre de la clase. Deberías estar diciendo

if (condition) { file = new A(); } else { file = new B(); }

"archivo" es la referencia aquí "fileHandler" es el nombre de la clase.

Aclamaciones.


La forma en que decida corregir esta advertencia realmente depende de lo que está tratando de hacer y de cuán estrictamente desea restringir los tipos permitidos para el parámetro de gen() .

Ejemplo 1

Muy flojo

abstract class E { public abstract void gen(fileHandler<?,?> A) throws Exception; } class C extends E { @Override public void gen(fileHandler<?,?> A) throws Exception {} }

Ejemplo 2

Restringir genérico Key para ser una String

abstract class E { public abstract void gen(fileHandler<String,?> A) throws Exception; } class C extends E { @Override public void gen(fileHandler<String,?> A) throws Exception {} }

Ejemplo 3

Probablemente desee nombrar el tipo no restringido para que pueda consultarlo.

abstract class E { public abstract <Value> void gen(fileHandler<String,Value> A) throws Exception; } class C extends E { @Override public <Value> void gen(fileHandler<String,Value> A) throws Exception {} }


No obtengo ningún error de compilación ... si soluciono todo el error en el código provisto

class fileHandler<Key, Value> { } class A extends fileHandler<String, String[]> { } class B extends fileHandler<String, String> { }

entonces

fileHandler file= null; if (/* condition */) { file = new A(); } else { file = new B(); }