Gilgamesz
Gilgamesz

Reputation: 5073

CHECKCAST is necessary or not?

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

Answers (1)

Kirill Simonov
Kirill Simonov

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

Related Questions