Switching on class literals

Brian Goetz brian.goetz at oracle.com
Tue Apr 12 20:40:16 UTC 2022


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>  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>  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