Switching on class literals

Nir Lisker nlisker at gmail.com
Sun Apr 10 18:33:33 UTC 2022


Hi,

Given the code example:

public class ClassLiterals {

    interface Vehicle {}

    class Car implements Vehicle {}

    class Boat implements Vehicle {}

    static Class<? extends Vehicle> createVehicleClass() { return
Car.class; }

    public static void main(String[] args) {
        Class<? extends Vehicle> vehicleClass = createVehicleClass();

        boolean b = switch (vehicleClass) {
            case Car.class -> true;
            case Boat.class -> true;
            default -> false;
        };

        boolean b2;
        if (vehicleClass == Car.class) {
            b2 = true;
        } else if (vehicleClass == Boat.class) {
            b2 = true;
        } else {
            b2 = false;
        }
    }
}

The case labels in the switch expression give the error:
incompatible types: Class<ClassLiterals.Car> cannot be converted to
Class<CAP#1>

Firstly, I understand that there is type erasure afoot. Secondly, the
if-else chain works, although I'm aware that there's some cheating involved
since it's not doing the parallel (illegal) instanceof check: if
(vehicleClass instanceof Class<Car>).
Using the == operator is guaranteed to work for class token comparison with
the caveat of being loaded with the same class loader, as far as I know.

Is it correct to say that Class<...> comparisons (switching and equality
checks) are special compared to other generic type comparisons?
Is there a reasonable way to make switch work for class literals if the
above is true?

Thanks,
Nir


More information about the amber-dev mailing list