Помилка в компіляторі eclipse або в javac (“параметри типу T неможливо визначити”)


74

Наступний код

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

компілюється в затемненні, але не з javac (параметри типу T визначити неможливо; не існує унікального максимального екземпляра для змінної типу T з верхніми межами T, java.lang.Object).

Коли я зміню readObject (String файл) на

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

він складається в затемненні і за допомогою javac. Хто правильний, компілятор затемнення чи javac?

Відповіді:


66

Я б сказав, що це помилка у компіляторі Sun, про яку повідомляється тут і тут , тому що якщо ви зміните рядок на нижчий, він буде працювати з обома, що, здається, саме те, що описано у звітах про помилки.

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

13

У цьому випадку я б сказав, що ваш код помилковий (і компілятор Sun має рацію). У вхідних аргументах немає нічого, що readObjectнасправді могло б зробити висновок про тип T. У такому випадку вам краще дозволити йому повернути Object і дозволити клієнтам вручну видавати тип результату.

Це має спрацювати (хоча я не тестував):

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

1
повернути GenericsTest2. <T> readObject (новий ObjectInputStream (новий FileInputStream (файл))); працює. Дякую!
Тобіас Шульте

1
Я не згоден, це більше схоже на помилку, пов'язану нижче. Компілятор повинен довіряти явному приведенню без виведення типу - наступна компіляція fine @SuppressWarnings ("не перевірено") public static <T> T createT (String className) кидає виняток {return (T) Class.forName (className) .newInstance () ; }
Дункан Макгрегор

3

Oracle JDK6 u22 повинен бути правильним, але у мене така проблема і з JDK6 u24

Це помилка затьмарення 98379 .

Це не було виправлено, але проблему вирішено шляхом обхідного рішення, як приклад у помилках затемнення (див. Посилання)


1

Я знайшов цю проблему в Java-версії "1.6.0_22". Він зник, коли я перейшов до версії Java "1.6.0_32", як це було виправлено в оновленні 25.


0

Якщо ви можете змінити метод readObject так, щоб він працював прозоро при виклику, ви також можете використовувати наступне:

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

Таким чином, абонент змушений вказати тип результату, і компілятор знає, як привести результат.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.