switch on Class ?

Remi Forax forax at univ-mlv.fr
Sun Aug 23 15:25:29 UTC 2020


There is a feature of Pizza (remember Generic Java ++) we have not discussed yet,
being able to do a switch on Class.

public sealed interface Numeric<T extends Numeric<T>>
  permits Amount, Percentage, Quantity {

  private BigDecimal value() {
    return switch(this) {
      case Amount(value) -> value;
      case Percentage(value) -> value;
      case Quantity(value) -> value;
    };
  }

  private static <T extends Numeric<T>> T fromValue(Class<T> type, BigDecimal newValue) {
    return type.cast(switch(type) {
      case Amount.class -> new Amount(newValue);
      case Percentage.class -> new Percentage(newValue);
      case Quantity.class -> new Quantity(newValue);
    });
  }

  default T add(T numeric) { return fromValue(getClass(), value().add(numeric.value())); }
}

with Amount be declared like this
  record Amount(BigDecimal value) implements Numeric<Amount> { }
  

This kind of switch is interesting because it's also one that can be exhaustive, like the switch on type or the switch on Enum.

In the method fromValue, type is typed as a Class<T> so a Class<? extends Numeric<...>> and given that Numeric is a sealed class only permitting Amount, Percentage and Quantity, the only possible Class for a switch(type) are Amount.class, Percentage.class and Quantity.class.

I'm pretty sure the call fromValue(getClass(), ...) doesn't not compile because the compiler has no idea that all subtypes of Numeric implements Numeric<themselves> but you get the idea. 

regards,
Rémi


More information about the amber-spec-observers mailing list