Java通配符泛型,在<?超级字符串上没有收到错误>但否则错误是"无法应用于Java.lang.String"



在使用泛型、通配符和函数式编程尝试一段代码时,我有一个疑问,下面是一个简单的程序

import java.util.function.Function;
public static void main(String[] args) {
String x = "";
String y = getFormData().apply(x);
}
private static Function<?, String> getFormData() {
return x -> ((String) x).concat("asd");
}

上面的程序在线上抛出一个错误

String y = getFormData().apply(x);

Function中的apply (capture<?>)不能应用于 (java.lang.String)

但是如果我将 getFormData() 函数更改为

private static Function<? super String, String> getFormData() {
return x -> ((String) x).concat("asd");
}

错误消失了。

有人可以解释为什么会发生这种情况吗?我知道<? super String>意味着任何超类型的字符串或字符串本身。

方法的第一个版本:

Function<?, String> getFormData() {...}

可以返回Function<Integer, String>.那么这个函数显然不能应用于String

但是,在第二种情况下:

Function<? super String, String> getFormData() {...}

不允许返回Function<Integer, String>

类型表达式Function<?, String>与任何返回StringFunction兼容,无论其参数类型如何。 例如,它与Function<Integer, String>. 因此,如果您没有比这更具体的信息,那么您就无法安全地将String或其他任何东西作为其apply方法的参数传递。 类型表达式未提供足够的信息来确定允许的参数类型。

另一方面,类型表达式Function<? super String, String>仅与接受String或其超类型之一作为参数(并返回String)的Function兼容。 将此类函数应用于String始终是安全的。 如果可以创建这样的子类,则将其应用于String子类的实例也是安全的。 然而,将其应用于任何其他类型是不安全的,即使是严格的超类型String,因为Function的第一个类型参数总是可以String本身。

总的来说,由于这意味着唯一可接受的参数类型是String,使用通配符似乎只会带来混乱。 我只会改用Function<String, String>

相关内容

  • 没有找到相关文章

最新更新