简体   繁体   中英

Generic Method Type Argument Inference Issue

I am unable to understand why second invocation below gives compiler error. Why is it not able to infer Number as type argument as in the first invocation?

typeArgInference(new Integer[100], new ArrayList<Number>()); // Infers Number

typeArgInference(new Number[100], new ArrayList<Integer>()); // compiler error

<T> void typeArgInference(T[] a, Collection<T> c) {}

May be I am missing something here. If there is any rule in JLS on this behavior, please do include the link.

Generics are invariant, arrays are covariant:

  • An Integer[] can act as a Number[] (because Integer is a subclass of Number )
  • An ArrayList<Integer> can't act as an ArrayList<Number> (because you can add eg a Double to the latter, but you mustn't add a Double into a list of Integer s).

Of course, you can try to put a Double into a Number[] , but it that would fail with ArrayStoreException if your Number[] is really an Integer[] . This would be a runtime failure.

Making arrays covariant was a fudge to have sort-of generic sort-of collections before the language supported generics. It was realized that this was a problem (because runtime failures suck), hence why generics were designed to be invariant.

Since you asked for JLS links:


Both of your examples would compile if you added an upper bound to the list type:

<T> void typeArgInference(T[] a, Collection<? extends T> c) {}

In both cases, Number is a type that would satisfy the type constraints:

  • Integer[] can act as a Number[] ; and ArrayList<Number> is a Collection<Number> , which is a Collection<? extends Number> Collection<? extends Number> .
  • Number[] can act as a Number[] (obviously); and ArrayList<Integer> is a Collection<Integer> , which is a Collection<? extends Number> Collection<? extends Number> .

You just then could not add anything into the Collection within that method (other than literal null ; or by breaking type safety via raw types).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM