0
class Test {
  static void foo(Class<?> clazz) {
    baz(clazz);
//    bar(clazz, clazz);    <------- THIS LINE ERRORS OUT
  }
  static <T> void bar(Class<T> type, Class<? extends T> subtype) {}

  static <T> void baz(Class<T> clazz) {
    bar(clazz, clazz);
  }
}

The post title might be too vague so edits are welcome. But basically in the code snippets above, calling bar directly from foo is not allowed. However, wrapping that call in baz (that does nothing more than calling bar) works.

Why is this counter-intuitive behavior? Is this a design flaw of the Java type system or a well grounded decision?

wlnirvana
  • 1,811
  • 20
  • 36
  • 1
    That's due to the wildcard. Even though the parameters for call in `bar factually has the "same ``" (since they are the same object), the compiler cannot infer this. – Turing85 Nov 07 '21 at 15:04
  • @Turing85 but why "the compiler cannot infer this"? I assume the compiler can infer that "they are the same object" (because IDE often hints something like `if (a==a)` is always true, even without real compilation). If the compiler is indeed capable of doing this, can't it further conclude the two parameters are of the exactly same type as well? – wlnirvana Nov 07 '21 at 15:19
  • The compiler could also resolve the [deadly diamond of death](https://en.wikipedia.org/wiki/Multiple_inheritance), and still, we have no multi-inheritance in java. Just because it could does not mean it does. If you are interested why exactly it does not work, try looking it up in the JLS (I try to avoid this part, generics are one of the... more complex parts of the JLS). – Turing85 Nov 07 '21 at 15:24

0 Answers0