Java 奇怪 class 转换异常
Java strange class cast exception
谁能帮我理解为什么在 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;
}
}
所以,method references(像String::trim
)有点奇怪;与 Java 中的大多数表达式不同,它们实际上没有自己的类型。像这样:
System.out.println((String::trim).getClass());
甚至不会编译,因为它没有给编译器足够的信息来说明 String::trim
应该是什么类型。
相反,每个方法引用的类型必须从周围的上下文中推断,例如通过作为赋值语句的右侧(使用左侧变量的类型)或直接传递给方法(使用方法参数的类型)。然后,编译器会为您生成一个 class,它使用相关方法实现了适当的类型。像这样:
final MagicFunction fun1 = String::trim;
实际上等同于:
final MagicFunction fun1 = new MagicFunction() {
public String apply(final String s) {
return s.trim();
}
};
请注意,这仅适用于特定类型,称为 "functional interface" 类型。 detailed rules 有点复杂,但基本思想是它必须是一个只有一个抽象方法的接口类型。方法参考提供了该方法的实现。 (当然,此方法的签名必须与方法引用的签名兼容;您不能使用 String::trim
来实现 Function<Integer, Integer>
。)
“当然,此方法的签名必须与方法引用的签名兼容;您不能使用 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);
}
谁能帮我理解为什么在 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;
}
}
所以,method references(像String::trim
)有点奇怪;与 Java 中的大多数表达式不同,它们实际上没有自己的类型。像这样:
System.out.println((String::trim).getClass());
甚至不会编译,因为它没有给编译器足够的信息来说明 String::trim
应该是什么类型。
相反,每个方法引用的类型必须从周围的上下文中推断,例如通过作为赋值语句的右侧(使用左侧变量的类型)或直接传递给方法(使用方法参数的类型)。然后,编译器会为您生成一个 class,它使用相关方法实现了适当的类型。像这样:
final MagicFunction fun1 = String::trim;
实际上等同于:
final MagicFunction fun1 = new MagicFunction() {
public String apply(final String s) {
return s.trim();
}
};
请注意,这仅适用于特定类型,称为 "functional interface" 类型。 detailed rules 有点复杂,但基本思想是它必须是一个只有一个抽象方法的接口类型。方法参考提供了该方法的实现。 (当然,此方法的签名必须与方法引用的签名兼容;您不能使用 String::trim
来实现 Function<Integer, Integer>
。)
“当然,此方法的签名必须与方法引用的签名兼容;您不能使用 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);
}