Hamcrest CombinableMatcher - generic method will not compile

I just looked at both and methods at org.hamcrest.core.CombinableMatcher in hamcrest 1.2

For some reason I cannot get the following command to compile

@Test public void testBoth() { String HELLO = "hello"; String THERE = "there"; assertThat("hello there", both(containsString(HELLO)).and(containsString(THERE))); } 

The compilation message I receive is

 and(org.hamcrest.Matcher<? super java.lang.Object>) in org.hamcrest.core.CombinableMatcher<java.lang.Object> cannot be applied to (org.hamcrest.Matcher<java.lang.String>) 

If I specify a type expression for a method, it works

 @Test public void testBoth() { String HELLO = "hello"; String THERE = "there"; Assert.assertThat("hello there", CombinableMatcher.<String> both(containsString(HELLO)).and(containsString(THERE))); } 

Although it is not so nice.

Can someone tell me why the compiler cannot define types here? I cannot believe that this is the expected behavior in this case.

Thanks!

+6
source share
2 answers

The compiler must conclude LHS <: String (ยง15.12.2.7 (A) , then (B) ), from which, of course, you can trivially infer LHS = String . JDK 7 distinguishes the specification (and you can specify the source and target as 5, as in javac -source 5 -target ).

+5
source

I hit a similar compilation error (when using java 1.8 and hamcrest 1.3), because my first match was nullValue() , which returns an Object type.

 assertThat(BigDecimal.ONE, is(both(not(nullValue())) .and(not(comparesEqualTo(BigDecimal.ZERO))))); ^---The method and(Matcher<? super Object>) in the type CombinableMatcher.CombinableBothMatcher<Object> is not applicable for the arguments (Matcher<BigDecimal>) 

If you use nullValue(BigDecimal.class) , it will compile.

 assertThat(BigDecimal.ONE, is(both(not(nullValue(BigDecimal.class))) .and(not(comparesEqualTo(BigDecimal.ZERO))))); 
+2
source

Source: https://habr.com/ru/post/907628/


All Articles