Reputation: 5073
package p;
public class X {
private int x;
public X supp(Function<Integer, X> f){
return f.apply( 1);
}
}
And bytecode for the supp
:
public supp(Ljava/util/function/Function;)Lp/X;
L0
LINENUMBER 24 L0
ALOAD 1
ICONST_1
INVOKESTATIC java/lang/Integer.valueOf (I)Ljava/lang/Integer;
INVOKEINTERFACE java/util/function/Function.apply (Ljava/lang/Object;)Ljava/lang/Object;
CHECKCAST p/X
ARETURN
L1
LOCALVARIABLE this Lp/X; L0 L1 0
LOCALVARIABLE f Ljava/util/function/Function; L0 L1 1
And the first version of bytecode is bit quirky for me, especially CHECKCAST p/X
.
I don't understand that. I know that there is a generic type erasure in runtime (so, in fact f.apply(1)
returns Object
instead of X
whileas supp
returns X
. So this check casting looks like java
(interpreter) would try to make sure that f.apply(1)
returns X
in fact.
But, why is it necessary? It looks like java
doesn't trust javac
. Basically, there is no real generic in Java- everyting based on type checking in compile time.
Upvotes: 1
Views: 1541
Reputation: 8491
The CHECKCAST
is necessary, because as a result of type erasure there is no information about function return type at runtime.
For example, nothing stops you from passing a raw Function
to the supp
method:
X x = new X();
Function f = o -> new Y();
x.supp(f);
This code compiles (with an unchecked assignment warning), but throws a ClassCastException
at runtime.
Upvotes: 3