2014-09-24 2 views
3

У меня есть класс, который несколько раз вызывает один из своих методов внутри. Все эти методы принимают общий параметр (Guava's Predicate). Eclipse компилирует эту информацию и не сообщает об ошибках и не имеет предупреждающих индикаторов, при этом параметры компилятора устанавливаются на совместимость с Java 1.6. Gradle (используя JDK 1.6.0_37) сообщает, что в один из таких случаев, когда метод называется, он не может найти символ для этого метода, но в других случаях он может. Это, по-видимому, связано с использованием статического метода Guava's Predicates#and(). Но аналогичный звонок с Guava's Predicates#not() работает.Ошибка компиляции дженериков с javac, но не Eclipse

я упростил код сводятся к следующему:

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(); 
    } 
} 

Результирующая ошибка компиляции является:

DoStuff (java.util.List, com.google.common.base.Predicate) в MyClass не может быть применен к (java.util.List, com.google.common.base.Predicate) return doStuff (l, и (p1, p2)); ^

Если я явно ввести вызов Predicates.and() следующим

return doStuff(l, Predicates.<String>and(p1, p2)); 

, то это прекрасно. Но мне не нужно это делать с вызовом Predicates.not() Он также работает, если я извлекаю выражение #and как локальную переменную.

  1. В чем разница между вызовом с помощью #and и вызов с помощью #not?
  2. Есть ли что-нибудь, что я могу сделать, чтобы избежать этого, что не включает в себя не набирать вызов and и не извлекать выражение and?
  3. И почему существует разница между компилятором градимента и компилятором Eclipse?
+1

AFAIK Gradle использует javac, который, как представляется, менее осведомлен о Java-дженериках, чем Eclipse. Однажды мне даже пришлось делать такие вещи, как «return (Something) (Object) x;», поскольку он утверждал, что приведение было невозможно, хотя оно сработало, и Eclipse вообще не жаловался. – maaartinus

+3

ad 3. Eclipse поставляется со своим собственным компилятором Java, Gradle использует JDK Java-компилятор. Это не редкость для двух, чтобы не согласиться на более тонкие аспекты языка Java (например, generics). Компилировать классы классов также могут отличаться, так как Eclipse и Gradle вычисляют эффективный путь класса компиляции по-разному. –

+0

Прямо на разных компиляторах. Вероятно, я не должен отмечать Gradle по этому вопросу, а скорее компилятор Oracle Javac vs Eclipse. Вопрос в том, какой из них «правильный»? Btw, я создаю проект Eclipse, используя цель Gclle 'eclipse'. –

ответ

0

раствор OP в

  1. Разница между and и not является то, что and определяет его общую подпись для своих параметров, как Predicate<? super T>, тогда как not использует простой параметр подписи Predicate<T>.
  2. Чтобы решить эту проблему, я определяю doStuffAnd с parm: Predicate<? super String>.