有没有人可以帮助我理解为什么在1种情况下我没有ClassCastException?至少String :: trim不是MagicFunction。
public class Main {
@FunctionalInterface
interface MagicFunction extends Function<String, String> {
}
public static void main(String[] args) throws IOException {
// 1. OK
final MagicFunction fun1 = String::trim;
// 2. java.lang.ClassCastException
Function<String, String> trim = String::trim;
final MagicFunction fun2 = (MagicFunction) trim;
}
}
答案 0 :(得分:3)
所以,method references(如String::trim
)有点奇怪;与Java中的大多数表达式不同,它们实际上没有自己的类型。像这样:
System.out.println((String::trim).getClass());
甚至不会编译,因为它没有给编译器足够的关于String::trim
应该是什么类型的信息。
相反,每个方法引用的类型必须从周围的上下文推断,例如通过作为赋值语句的右侧(使用左侧变量的类型)或直接传递给方法(使用方法参数的类型)。然后编译器为您生成一个类,使用相关方法实现适当的类型。像这样:
final MagicFunction fun1 = String::trim;
实际上等同于:
final MagicFunction fun1 = new MagicFunction() {
public String apply(final String s) {
return s.trim();
}
};
请注意,这仅适用于特定类型,称为“功能接口”类型。 detailed rules有点复杂,但基本思想是它必须是一个只有一个抽象方法的接口类型。方法参考提供该方法的实现。 (当然,此方法的签名必须与方法引用的签名兼容;您不能使用String::trim
来实现Function<Integer, Integer>
。)
答案 1 :(得分:-2)
“当然,这个方法的签名必须与方法引用的签名兼容;你不能使用String::trim来实现Function
String g = "testString";
testMethod(String::trim, g);
public static <T, R> void testMethod(Function<T, R> func, T t) {
func.apply(t);
}