When is generic return value of function casted after type erasure?

前端 未结 3 2029
孤街浪徒
孤街浪徒 2020-12-05 19:33

This question was inducted by this StackOverflow question about unsafe casts: Java Casting method without knowing what to cast to. While answering the question I encount

3条回答
  •  挽巷
    挽巷 (楼主)
    2020-12-05 20:31

    If you can't find it in the specification, that means it's not specified, and it is up to the compiler implementation to decide where to insert casts or not, as long as the erased code meets the type safety rules of non-generic code.

    In this case, the compiler's erased code looks like this:

    public static Object identity(Object x) {
        return x;
    }
    public static void main(String args[]) {
        String a = (String)identity("foo");
        System.out.println(a.getClass().getName());
    
        Object b = identity("foo");
        System.out.println(b.getClass().getName());
    }
    

    In the first case, the cast is necessary in the erased code, because if you removed it, the erased code wouldn't compile. This is because Java guarantees that what is held at runtime in a reference variable of reifiable type must be instanceOf that reifiable type, so a runtime check is necessary here.

    In the second case, the erased code compiles without a cast. Yes, it will also compile if you added a cast. So the compiler can decide either way. In this case, the compiler decided not to insert a cast. That is a perfectly valid choice. You should not rely on the compiler to decide either way.

提交回复
热议问题