<div dir="ltr"><div>Hello!</div><div><br></div><div>I don't remember whether switch on java.lang.Class instance was discussed. I guess, this pattern is quite common and it will be useful to support it. Such code often appears in deserialization logic when we branch on desired type to deserialize. Here are a couple of examples from opensource libraries:</div><div><br></div><div>1. com.google.gson.DefaultDateTypeAdapter#read (gson-2.8.2):</div><div><br></div><div>  Â  Date date = deserializeToDate(in.nextString());</div><div>  Â  if (dateType == Date.class) {</div><div>  Â  Â  return date;</div><div>  Â  } else if (dateType == Timestamp.class) {</div><div>  Â  Â  return new Timestamp(date.getTime());</div><div>  Â  } else if (dateType == java.sql.Date.class) {</div><div>  Â  Â  return new java.sql.Date(date.getTime());</div><div>  Â  } else {</div><div>  Â  Â  // This must never happen: dateType is guarded in the primary constructor</div><div>  Â  Â  throw new AssertionError();</div><div>  Â  }</div><div><br></div><div>Could be rewritten as:</div><div><br></div><div>  Â  Date date = deserializeToDate(in.nextString());</div><div>  Â  return switch(dateType) {</div><div>  Â  Â  case Date.class -> date;</div><div>  Â  Â  case Timestamp.class -> new Timestamp(date.getTime());</div><div>  Â  Â  case java.sql.Date.class -> new java.sql.Date(date.getTime());</div><div>  Â  Â  default -></div><div>  Â  Â  Â  // This must never happen: dateType is guarded in the primary constructor</div><div>  Â  Â  Â  throw new AssertionError();</div><div>  Â  };</div><div><br></div><div>2. com.fasterxml.jackson.databind.deser.std.FromStringDeserializer#findDeserializer (jackson-databind-2.9.4):</div><div><br></div><div>  Â  public static Std findDeserializer(Class<?> rawType)</div><div>  Â  {</div><div>  Â  Â  Â  int kind = 0;</div><div>  Â  Â  Â  if (rawType == File.class) {</div><div>  Â  Â  Â  Â  Â  kind = Std.STD_FILE;</div><div>  Â  Â  Â  } else if (rawType == URL.class) {</div><div>  Â  Â  Â  Â  Â  kind = Std.STD_URL;</div><div>  Â  Â  Â  } else if (rawType == URI.class) {</div><div>  Â  Â  Â  Â  Â  kind = Std.STD_URI;</div><div>  Â  Â  Â  } else if (rawType == Class.class) {</div><div>  Â  Â  Â  Â  Â  kind = Std.STD_CLASS;</div><div>  Â  Â  Â  } else if (rawType == JavaType.class) {</div><div>  Â  Â  Â  Â  Â  kind = Std.STD_JAVA_TYPE;</div><div>  Â  Â  Â  } else if // more branches like this</div><div>  Â  Â  Â  } else {</div><div>  Â  Â  Â  Â  Â  return null;</div><div>  Â  Â  Â  }</div><div>  Â  Â  Â  return new Std(rawType, kind);</div><div>  Â  }</div><div><br></div><div>Could be rewritten as:</div><div><br></div><div>  Â  public static Std findDeserializer(Class<?> rawType)</div><div>  Â  {</div><div>  Â  Â  Â  int kind = switch(rawType) {</div><div>  Â  Â  Â  case File.class -> Std.STD_FILE;</div><div>  Â  Â  Â  case URL.class -> Std.STD_URL;</div><div>  Â  Â  Â  case URI.class -> Std.STD_URI;</div><div>  Â  Â  Â  case Class.cass -> Std.STD_CLASS;</div><div>  Â  Â  Â  case JavaType.class -> Std.STD_JAVA_TYPE;</div><div>  Â  Â  Â  ...</div><div>  Â  Â  Â  default -> 0;</div><div>  Â  Â  Â  };</div><div>  Â  Â  Â  return kind == 0 ? null : new Std(rawType, kind);</div><div>  Â  }</div><div><br></div><div>In such code all branches are mutually exclusive. The bootstrap method can generate a lookupswitch based on Class.hashCode, then equals checks, pretty similar to String switch implementation. Unlike String hash codes Class.hashCode is not stable and varies between JVM launches, but they are already known during the bootstrap and we can trust them during the VM lifetime, so we can generate a lookupswitch. The minor problematic point is to support primitive classes like int.class. This cannot be passed directly as indy static argument, but this can be solved with condy.</div><div><br></div><div>What do you think?</div><div><br></div><div>With best regards,</div><div>Tagir Valeev.</div><div><br></div></div>