Switching on class literals

Nir Lisker nlisker at gmail.com
Tue Apr 12 22:04:47 UTC 2022


Got it, thanks.

On Tue, Apr 12, 2022 at 11:40 PM Brian Goetz <brian.goetz at oracle.com> wrote:

> You are right that there has been some progress, but I think we're not
> quite ready to confront this yet.  One of the items that we have not yet
> integrated is how we are going to handle "constant patterns".  Right now,
> constant case labels (e.g., `case"Foo"`) are not patterns, but simply
> alternate forms of case labels.  We envision possibly raising them up to
> full patterns some day, but are not yet satisfied with the options.  I'm
> reluctant to add new kinds of constant case labels before we make more
> progress with constant patterns -- which is still a lower priority than a
> lot of other things (we have workarounds, such as `when` clauses.)
>
>
>
> On 4/11/2022 9:22 AM, Nir Lisker wrote:
>
> Hi Tagir,
>
> I went through them, thanks (I'm not subbed to the specs lists). Looks like
> I'm in time for the once-every-two-years discussion on this. There have
> been quite a few advances since.
>
> On Mon, Apr 11, 2022 at 10:52 AM Tagir Valeev <amaembo at gmail.com> <amaembo at gmail.com> wrote:
>
>
> Hello, Nir!
>
> To add some context, switch over class literals was already discussed
> at least twice. See the following threads:
> https://mail.openjdk.java.net/pipermail/amber-spec-experts/2018-April/000531.html
> https://mail.openjdk.java.net/pipermail/amber-spec-observers/2020-August/002515.html
>
> With best regards,
> Tagir Valeev
>
> On Mon, Apr 11, 2022 at 1:34 AM Nir Lisker <nlisker at gmail.com> <nlisker at gmail.com> wrote:
>
> 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