Следующий пример успешно компилируется в Java 7 и не компилируется в Java 8 (и новее).
public abstract class Example<T>
{
public T method()
{
return method(new HashMap());
}
abstract T method(Map<String, String> arg);
}
Java 7:
BUILD SUCCESSFUL in 1s
Java 8:
> Task :compileJava FAILED
C:\dev\projects\Java8\src\main\java\example\Example.java:10: error: incompatible types: Object cannot be converted to T
return method(new HashMap());
^
where T is a type-variable:
T extends Object declared in class Example
Ошибка выше означает, что method(new HashMap())
вернул Object
вместо ожидаемого T
.
Чтобы избежать этой ошибки в Java 8, я должен предоставить аргумент универсального типа, то есть изменить new HashMap()
наnew HashMap<>()
.
Тревожная часть заключается в том, что ошибка, вызванная необработанным аргументом типа, переданным method(Map<String, String>)
, фактически связана с тем, что этот метод возвращает Object
вместо T
.Поэтому я могу ожидать:
T result = method(new HashMap<>());
..., но:
Object result = method(new HashMap());
Кажется, что интуитивное поведение не является параметризованным типом возврата метода, внезапно забываемым, если неАргумент универсального типа предоставляется там, где ожидается аргумент универсального типа.Это просто контекст аргумента в определении метода, который я ожидаю изолировать от контекста типа возврата в том же определении метода.
Есть ли обоснованиеа применимо объяснение такого поведения?Я знаю об изменениях, затрагивающих обобщение, сделанное в Java 8, но ничего не соответствует этому конкретному случаю.
Спасибо за ваши ответы.