Обобщения - это только проверка времени компиляции (читайте о стирании типа ). Итак, во время выполнения ваш getSomething()
метод выглядит примерно так:
static Object getSomething(Function fun) {
return fun;
}
Теперь вы ясно видите, что первая строка никогда не выдаст исключение
Scratch.getSomething(x -> "hello");
, поскольку Function
является Object
и, следовательно, может быть возвращено без проблем.
Вторая строка, однако, будет бросать одну, потому что она будет выглядеть примерно так:
String something = (String) Scratch.getSomething(x -> "hello");
A Function
по-прежнему Object
, поэтому его можно вернуть из метода, но это не String
и, таким образом, вы получите ClassCastException
.
Код прекрасно компилируется, потому что вы указываете компилятору, что знаете, что делаете. Вы получите предупреждение Unchecked cast
в этой строке:
return (T) fun;
Это предупреждение должно указывать вам, программисту, на то, что он (компилятор) не может быть уверен, что приведение выполнится успешно.