Error compiling generics with javac but not Eclipse
I have a class that calls one of its own methods multiple times. All of these methods take a common parameter (Guava Predicate
). Eclipse compiles this information and reports no errors or warning indicators, and sets the compiler options to be Java 1.6 compliant. Gradle (using JDK 1.6.0_37) reports that in one such case, when a method is called, it cannot find a symbol for that method, but in other cases it can. This appears to be due to the use of Guava's static method Predicates#and()
. But a similar call works with Guava Predicates#not()
.
I've simplified the code to the following:
import static com.google.common.base.Predicates.and;
import static com.google.common.base.Predicates.not;
import com.google.common.base.Predicate;
import com.google.common.base.Predicates;
import com.google.common.collect.FluentIterable;
public class MyClass {
public List<String> doStuffAnd(List<String> l, Predicate<String> p1, Predicate<String> p2) {
// eclipse fine, gradle complains it can't find symbol doStuff
return doStuff(l, and(p1, p2));
}
public List<String> doStuffNot(List<String> l, Predicate<String> p) {
// both eclipse and gradle compile fine
return doStuff(l, not(p));
}
public List<String> doStuff(List<String> l, Predicate<String> p) {
return FluentIterable.from(l).filter(p).toList();
}
}
Resulting compilation error:
DoStuff (java.util.List, com.google.common.base.Predicate) in MyClass cannot be applied to (Java.util.List, com.google.common.base.Predicate) return doStuff (l and (p1, p2) ); ^
If I explicitly dial the call Predicates.and()
like this
return doStuff(l, Predicates.<String>and(p1, p2));
then that's okay. But I don't need to do this with a call Predicates.not()
It also works if I retrieve the expression #and
as a local variable.
- What is the difference between calling with
#and
and calling with#not
? - Is there anything I can do to avoid this that does not require invocation input
and
or expression highlightingand
? - And why is there a difference between the Gradle compiler and the Eclipse compiler?
source to share
OP's solution
- The difference between
and
andnot
is that itand
defines its generic signature for its parameters asPredicate<? super T>
, whereas itnot
uses a simple parameter signaturePredicate<T>
. - To solve this problem, I identify
doStuffAnd
with the help of the parm:Predicate<? super String>
.
source to share