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?

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

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

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).


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.


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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.