java泛型,对extends和super的澄清

时间:2018-02-18 19:09:41

标签: java generics

这是CompletionStage的类定义

public interface CompletionStage<T> {
...
}

这是方法thenApply

public <U> CompletionStage<U> thenApply(Function<? super T,? extends U> fn);

我的问题是:为什么要服用? super T 作为函数的第一个参数......不应该是吗?扩展T ,因为T的任何子类都可以转换为T?并且任何超级T都不能被强制转换为T ??

1 个答案:

答案 0 :(得分:2)

我通过询问哪个签名最有意义来解决这个问题?有三种选择:

  • Function<T, ? extends U>
  • Function<? super T, ? extends U>
  • ? extends T

首先,T不包含Function<T, U>。因此,您无法将CompletionStage<T>传递给? extends T,这可能会出乎意料。所以T不是最好的选择。

这使我们只需? super TT

简单Function<T, U>适用于? super T,就像? super T一样。但哪个更好? T允许您应用参数T或超级T的函数。与简单CompletionStage<Integer>.thenApply(Function<Number, String>)相比,这更灵活,因为您可以使用更多通用函数。例如,您可以使用简单的T执行? super T? super T似乎也没有任何缺点,至少我没有看到任何缺点。

所以从我的观点来看,data <- read.table(text="Company Tag CompanyA TagA CompanyA TagB CompanyA TagC CompanyB TagA CompanyB TagB CompanyB TagC CompanyB TagD CompanyB TagE CompanyB TagF CompanyC TagA CompanyC TagB CompanyC TagC CompanyC TagD ",header=TRUE) library(reshape2) d = dcast(data,Company~Tag,value.var = "Tag") names(d)[grep("^Tag", names(d))] = paste("Tag", 1:(ncol(d)-1), sep = "" ) 显然是更好的选择。