Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Restrict generic types to super types on a method [duplicate]

Tags:

java

generics

I have a list decorator that should, amongst a lot of other things, allow casting from one list to another. The idea is like that, and it already works:

public class ExtendedList<T> implements List<T> {

    private List<T> delegate;

    // constructors, methods, a collector, etc

    public <R> ExtendedList<R> castTo(Class<R> targetType) {
        return delegate.stream().map(item -> (R) item).collect(ExtendedList.toList());
    }
}

I wonder if (and how) it is possible to restrict type parameter R to valid casting targets like T, all superclasses of T and all interfaces that T implements, so that the compiler can already check if casting is possible when I use it:

ExtendedList<Vehicle> vehicles = cars.castTo(Vehicle.class);  // assuming Car implements Vehicle -> OK
ExtendedList<Dog> dogs = cars.castTo(Dog.class);              // assuming Car does not extend Dog -> not OK
like image 655
Andreas Dolk Avatar asked Dec 05 '25 05:12

Andreas Dolk


1 Answers

You can do it with a static method:

public <R> ExtendedList<R> castToUnchecked() {
    return delegate.stream().map(item -> (R) item).collect(ExtendedList.toList());
}

public static <R, U extends R> ExtendedList<R> castTo(ExtendedList<U> l) {
    return l.<R>castToUnchecked();
}

Which ensures that R is a superclass of U, used as:

ExtendedList<Vehicle> vehicles = ExtendedList.<Vehicle>castTo(cars);
ExtendedList<Dog> dogs = ExtendedList.<Dog>castTo(cars);  // error: `Car` doesn't extend `Dog`
like image 182
Artyer Avatar answered Dec 07 '25 19:12

Artyer