arguments? There is a method in the hamcrest library: package org....">

For a method of type T, what should be its type "deduced" when two <? super T> arguments?

There is a method in the hamcrest library:

package org.hamcrest.core ... public static <T> Matcher<T> allOf(Matcher<? super T> first, Matcher<? super T> second) { List<Matcher<? super T>> matchers = new ArrayList<Matcher<? super T>>(2); matchers.add(first); matchers.add(second); return allOf(matchers); } 

In my code, I call this method first Matcher<Object> and second Matcher<SomeException> .

And now:

  • When I compile it with Eclipse with a 1.6 target, it makes a <T> Matcher<SomeException> .
  • When I compile it with javac 1.7 with a 1.6 target, it makes a <T> Matcher<SomeException> .
  • When I compile it with javac 1.6 with a 1.6 target, it makes a <T> Matcher<Object>

The question is, what should <T> be in that case?

I understand that there is an error in javac 1.6, and it should be Matcher<SomeException> , since this is a common type of input arguments (SomeException is a subtype of Object), and then it is 100% sure that the Matcher Returned will be Matcher<SomeException> .

I'm right? And is there a way to get Javac 1.6 to behave properly?

+7
source share
2 answers

The compiler will produce output based on the actual arguments . It starts with the initial constraints of Matcher<Object> << Matcher<? super T> Matcher<Object> << Matcher<? super T> and Matcher<SomeException> << Matcher<? super T> Matcher<SomeException> << Matcher<? super T> . From this we derive the constraints T << Object and T << SomeException . Object will be eliminated when the minimum erased candidate set is configured. The rest of the SomeException candidate will (eventually: D) be replaced by T

So far, we have shown that Eclipse and JDK7 behave correctly in this case. I don't think there is a way to get Javac to behave properly. You can either explicitly specify a type argument or use JDK7 (specify source and target as 6).

+3
source

There are two things you should consider:

  • First you can use it like this: CoreMatcher.<SomeException>allOf(...) , which explicitly sets T

  • Secondly, due to type erasure, you ALWAYS have a Matcher<Object> as the runtime. Therefore, in any case, the runtime behavior is the same.

+1
source

All Articles