JavaFX FilteredList泛型getPredicate()

时间:2017-09-21 17:42:27

标签: java generics javafx

我刚刚遇到了一个不可能的泛型方法。我似乎无法编写一个方法,该方法采用JavaFX过滤列表和谓词,并简单地使用传入的谓词来过滤列表谓词。唯一的方法是在某些情况下投射哪个会导致ClassCastException或使用Raw类型。我认为java不能代表<? super <? super String>>。如果我遗漏了任何东西,有人能发现吗?

import javafx.collections.transformation.FilteredList;
import java.util.function.Predicate;
public class Test {
  void and(FilteredList<String> l, Predicate<? super String> predicate) { //Impossible generics on 2nd parameter
    l.getPredicate().and(predicate);
  }
}

使用Predicate<? super Object>不起作用,因为它不够通用:

public class Test {
  <T> Predicate<? super T> and(FilteredList<T> l, Predicate<? super Object> predicate) {
      return l.getPredicate().and(predicate);
  }

  public void exampleCall(FilteredList<Integer> integers, Predicate<Number> numberPredicate) {
     return and(integers, numberPredicate); // doesn't compile
  }
}

1 个答案:

答案 0 :(得分:0)

你可以做到

void and(FilteredList<String> l, Predicate<? super Object> predicate) { 
    l.getPredicate().and(predicate);
}

这几乎是唯一有意义的事情。 FilteredList<String>上的谓词的类型为Predicate<? super String>,这是有道理的,因为在那里使用Predicate<Object>是完全有效的。所以(如果您原谅轻微滥用语法)FilteredList<String>.getPredicate()会返回一个谓词,该谓词可以应用于String的某些未知(但特定)超类型。

传递给and() Predicate<T>方法的参数的要求是它必须能够测试T类型的对象,所以它是有意义的一个Predicate<? super T>

因此,传递给l.getPredicate().and(...)的类型必须是可以应用于? super String的谓词,即可以应用于String的某个未知超类型:最具体的类型是? super Object

(在整个过程中,我使用的是泛型术语中使用的惯例,类型T被认为是自身的超类型,所以{&#34;超级类型T&#34;我的意思是&#34; T或其中一个超类&#34;等。)

请注意,生成的表达式的类型为Predicate<? super String>,因此您可以执行

Predicate<? super String> and(FilteredList<String> l, Predicate<? super Object> predicate) {
    return l.getPredicate().and(predicate);
}