Why first line in main does not throw ClassCastException while the second does?
import java.util.function.Function;
class Scratch {
static <T> T getSomething(Function<Integer, T> fun) {
return (T) fun;
}
public static void main(String[] args) {
Scratch.<String>getSomething(x -> "hello");
String something = Scratch.<String>getSomething(x -> "hello");
}
}
The difference is because you don't use the result of the method in the first case, but you do in the second.
A cast is an expression, but it's not a StatementExpression
. This means that you can't write this:
(String) somethingReturningAString();
but you can write:
String aString = (String) somethingReturningAString();
At compile time, the compiler inserts checkcast
instructions where it needs to, and where it can:
String
to a String
variable. As such, it checks the cast, and that fails.It's worth noting that there are some perhaps unexpected cases where a cast isn't strictly necessary, but is inserted. For example:
Scratch.<String>getSomething(x -> "hello").toString();
would fail with a ClassCastException
, since it would be transformed to:
((String) Scratch.getSomething(x -> "hello")).toString();
even though Object
has a toString()
method, and so it could invoke that without a cast.