web-dev-qa-db-fra.com

Bug dans le compilateur Eclipse ou dans javac ("les paramètres de type de T ne peuvent pas être déterminés")

Le code suivant

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();
    }
}

compile dans Eclipse, mais pas avec javac (les paramètres de type de T ne peuvent pas être déterminés; aucune instance maximale unique n'existe pour la variable de type T avec les limites supérieures T, Java.lang.Object). 

Lorsque je remplace readObject (fichier de chaîne) par 

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

il se compile en Eclipse et avec javac. Qui a raison, le compilateur Eclipse ou javac?

74
Tobias Schulte

Je dirais que c'est le bogue du compilateur Sun signalé ici et ici , car si vous modifiez votre ligne par celle ci-dessous, cela fonctionne avec les deux, ce qui semble être exactement ce qui est décrit dans le bogue rapports.

return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file)));
66
Fabian Steeg

Dans ce cas, je dirais que votre code est incorrect (et que le compilateur Sun a raison). Il n'y a rien dans vos arguments en entrée à readObject pour en déduire le type T. Dans ce cas, il est préférable de le laisser renvoyer un objet et aux clients d'envoyer manuellement le type de résultat.

Cela devrait fonctionner (même si je ne l'ai pas testé):

public static <T> T readObject(String file) throws Exception {
    return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file)));
}
13
Chris Jester-Young

Oracle JDK6 u22 devrait être correct mais j'ai aussi ce problème avec JDK6 u24

Ceci est un bogue d'Eclipse bogue 98379 .

Ce problème n'a pas été corrigé, mais le problème est résolu via une solution de contournement, comme dans l'exemple des bogues Eclipse (voir lien).

3
m.genova

J'ai trouvé ce problème dans la version Java "1.6.0_22". Il a disparu lors de la mise à niveau vers la version Java "1.6.0_32", corrigé dans la mise à jour 25.

1
RJC

Si vous pouvez modifier votre méthode readObject pour qu'elle fonctionne de manière transparente lorsqu'elle est appelée, vous pouvez également utiliser les éléments suivants:

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

De cette façon, l'appelant est obligé de spécifier le type du résultat et le compilateur sait comment convertir le résultat.

0
OndroMih