Fehler im Eclipse-Compiler oder in Javac ("Typparameter von T können nicht bestimmt werden")

74

Der folgende Code

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

Kompiliert in Eclipse, jedoch nicht mit Javac (Typparameter von T können nicht bestimmt werden; für die Typvariable T mit den oberen Grenzen T, java.lang.Object, existiert keine eindeutige maximale Instanz).

Wenn ich readObject (String file) in ändere

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

es kompiliert in Eclipse und mit Javac. Wer ist richtig, der Eclipse-Compiler oder Javac?

Tobias Schulte
quelle

Antworten:

66

Ich würde sagen, es ist der Fehler im Sun-Compiler, der hier und hier gemeldet wurde , denn wenn Sie Ihre Zeile in die folgende ändern, funktioniert dies mit beiden, was genau das zu sein scheint, was in den Fehlerberichten beschrieben wird.

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

In diesem Fall würde ich sagen, dass Ihr Code falsch ist (und der Sun-Compiler richtig ist). Ihre Eingabeargumente enthalten nichts readObject, was auf den Typ schließen könnte T. In diesem Fall ist es besser, wenn Sie Object zurückgeben und Clients den Ergebnistyp manuell umwandeln lassen.

Dies sollte funktionieren (obwohl ich es nicht getestet habe):

public static <T> T readObject(String file) throws Exception {
    return GenericsTest2.<T>readObject(new ObjectInputStream(new FileInputStream(file)));
}
Chris Jester-Young
quelle
1
return GenericsTest2. <T> readObject (neuer ObjectInputStream (neuer FileInputStream (Datei))); funktioniert. Vielen Dank!
Tobias Schulte
1
Ich bin anderer Meinung, es sieht eher nach dem unten genannten Fehler aus. Der Compiler sollte einer expliziten Umwandlung ohne Typinferenz vertrauen - die folgenden kompilieren fein @SuppressWarnings ("nicht markiert") public static <T> T createT (String className) löst eine Ausnahme aus {return (T) Class.forName (className) .newInstance () ;; }
Duncan McGregor
3

Oracle JDK6 u22 sollte korrekt sein, aber ich habe dieses Problem auch mit JDK6 u24

Dies ist ein Fehler des Eclipse- Fehlers 98379 .

Dies wurde nicht behoben, aber das Problem wird durch eine Problemumgehung wie in Eclipse-Fehlern behoben (siehe Link).

m.genova
quelle
1

Ich habe dieses Problem in der Java-Version "1.6.0_22" gefunden. Es verschwand, als ich auf die Java-Version "1.6.0_32" aktualisierte, da dies in Update 25 behoben wurde.

RJC
quelle
0

Wenn Sie Ihre Methode readObject so ändern können, dass sie beim Aufruf transparent funktioniert, können Sie auch Folgendes verwenden:

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

Auf diese Weise muss der Aufrufer den Typ des Ergebnisses angeben, und der Compiler weiß, wie das Ergebnis umgewandelt wird.

OndroMih
quelle