Search code examples
javacasting

Why is an explicit cast required when returning a type intersection?


Nicolai Parlog's blog post on intersection types with var shows a method, createCloseableIterator(), that returns an intersection type:

@SuppressWarnings("unchecked")
private static <T extends Closeable & Iterator<String>>
        T createCloseableIterator(boolean empty) {
    if (empty)
        return (T) new Empty();
    else
        return (T) new Scanner(System.in);
}

where Empty and Scanner both implement Iterator<String> and Closeable.

Why are the explicit casts to (T) needed?


Solution

  • It's not because of the type intersection, it's because you're returing a T, which is chosen by the caller of the method and could be a different type that is not a Scanner or an Empty.

    This would result in a class cast exception if you attempt to store the result in a variable of the other chosen type, for example:

    class Other implements Closeable, Iterator<String> { ... }
    
    Other e = createCloseableIterator(false);