2008-11-24 9 views
74

El siguiente códigoBug en compilador Eclipse o en javac ("parámetros de tipo de T no pueden determinarse")

public class GenericsTest2 { 

    public static void main(String[] args) throws Exception { 
     Integer i = readObject(args[0]); 
     System.out.println(i); 
    } 

    public static <T> T readObject(String file) throws Exception { 
     return readObject(new ObjectInputStream(new FileInputStream(file))); 
     // closing the stream in finally removed to get a small example 
    } 

    @SuppressWarnings("unchecked") 
    public static <T> T readObject(ObjectInputStream stream) throws Exception { 
     return (T)stream.readObject(); 
    } 
} 

compila en eclipse, pero no con javac (parámetros de tipo de T no pueden determinarse; no único la instancia máxima existe para la variable de tipo T con límites superiores T, java.lang.Object).

Cuando cambio readObject (archivo String) para

@SuppressWarnings("unchecked") 
    public static <T> T readObject(String file) throws Exception { 
     return (T)readObject(new ObjectInputStream(new FileInputStream(file))); 
    } 

se compila en Eclipse y con javac. ¿Quién está correcto, el compilador de eclipse o javac?

Respuesta

66

Yo diría que es el error en el compilador de Sun informó here y here, porque si cambia su línea a la que está debajo funciona con ambos, que parece ser exactamente lo que se describe en los informes de errores.

return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file))); 
13

En este caso, diría que su código es incorrecto (y el compilador de Sun está en lo cierto). No hay nada en sus argumentos de entrada al readObject que realmente infiera el tipo T. En ese caso, es mejor dejar que devuelva Object y dejar que los clientes seleccionen manualmente el tipo de resultado.

Esto debería funcionar (aunque no lo he probado):

public static <T> T readObject(String file) throws Exception { 
    return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file))); 
} 
+1

return GenericsTest2. readObject (nuevo ObjectInputStream (nuevo FileInputStream (archivo))); funciona. ¡Gracias! –

+1

No estoy de acuerdo, se parece más al error relacionado a continuación. El compilador debe confiar en una conversión explícita y sin inferencia de tipos - la siguiente compila bien @SuppressWarnings ("sin marcar") pública estática T createT (String className) throws Exception { de retorno (T) Class.forName (className) .newInstance(); } –

3

Oracle JDK6 U22 debe ser correcta pero no tengo este problema con JDK6 u24 demasiado

Esto es un error de Eclipse bug 98379.

Esto no fue corregido pero el problema se resuelve por medio de solución como ejemplo de los errores de eclipse (ver enlace)

0

Si usted puede modificar su método readObject a trabajar de forma transparente cuando se le llama, también puede utilizar lo siguiente:

public static <T> T readObject(String file, Class<T> type) throws Exception { 
    return type.cast(readObject(new ObjectInputStream(new FileInputStream(file)))); 
} 

De esta manera, la persona que llama se ve obligada a especificar el tipo de resultado y el compilador sabe cómo emitir el resultado.

1

Encontré este problema en la versión de Java "1.6.0_22". Desapareció cuando actualicé a la versión de Java "1.6.0_32", ya que se corrigió en la actualización 25.

Cuestiones relacionadas