In a type switch, the indy call the type is erased to Object

Remi Forax forax at univ-mlv.fr
Thu Aug 26 18:59:56 UTC 2021


If fizzbuzz is written like this

import static java.util.stream.IntStream.rangeClosed;

public interface PatternFizzBuzz {
  static String fizzbuzz(int i) {
    return switch((Integer) i) {
      case Integer v && v % 15 == 0 -> "FizzBuzz";
      case Integer v && v % 5 == 0 -> "Buzz";
      case Integer v && v % 3 == 0 -> "Fizz";
      case Integer v -> "" + v;
    };
  }

  static void main(String[] args) {
    rangeClosed(1, 100).mapToObj(i -> fizzbuzz(i)).forEach(System.out::println);
  }
}

the generated code by javac is

public static java.lang.String fizzbuzz(int);
    Code:
       0: iload_0
       1: invokestatic  #1                  // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
       4: astore_1
       5: iconst_0
       6: istore_2
       7: aload_1
       8: iload_2
       9: invokedynamic #7,  0              // InvokeDynamic #0:typeSwitch:(Ljava/lang/Object;I)I
      14: tableswitch   { // -1 to 2
                    -1: 112
                     0: 44
                     1: 66
                     2: 89
               default: 112
          }
      44: ...

Why the method type of invokedynamic is (Ljava/lang/Object;I)I and not (Ljava/lang/Integer;I)I ?

It's like if the type is erased ?
This is important here because we statically now that the selector value is always an Integer.

regards,
Rémi


More information about the amber-dev mailing list