提问人:DashwoodIce9 提问时间:7/24/2023 更新时间:7/24/2023 访问量:69
在 Java 中使用函数接口时是否有隐式类型转换?
Is there an implicit type casting when using Functional Interfaces in Java?
问:
我编写了以下 Java 代码并期望它不会编译,但它确实编译并且执行了违反直觉。我正在使用 Java 17。
TestFunctionExecutor.java
@FunctionalInterface
public interface TestFunctionExecutor{
void execute();
}
TestClass.java
public class TestClass{
public static void main(String... args) {
TestClass test = new TestClass();
test.wrapper(test::sampleFunction);
}
public void sampleFunction() {
System.out.println("Inside sampleFunction");
}
public void wrapper(TestFunctionExecutor method) {
System.out.println("Before method execution");
method.execute();
System.out.println("After method execution");
}
}
输出-
Before method execution
Inside sampleFunction
After method execution
我认为,既然需要一个类型的参数,并且我正在传递一个类型的参数,那么编译应该会失败。我使用了一个调试器,看起来像是在运行时。这让我感到困惑,我有几个问题——wrapper
TestFunctionExecutor
TestClass
method
TestClass$$Lambda$1...
- 是什么类型的?不是还是类似的东西?我无法用调试器推断出这一点。
test::SampleFunction
TestClass
TestClass$$sampleFunction...
- 为什么这里没有错误?看起来这些类型以某种方式变得兼容,如何?
- 如何知道要执行什么代码?
execute
- 这是好代码吗?我的目标是包装一个函数,以便一些代码在它之前和之后运行。
谢谢!
答:
2赞
Baptiste Beauvais
7/24/2023
#1
在 Java 中,lambda 表达式只是 Anonymous 类的一种语法,它基本上是使用 JVM 创建的名称当场创建的类。
您的代码可以以 4 种方式(从更简洁到更不简洁)编写:
test.wrapper(test::sampleFunction);
test.wrapper(() -> test.sampleFunction());
test.wrapper(() -> {
test.sampleFunction();
});
test.wrapper(new TestFunctionExecutor() {
public void execute() {
test.sampleFunction();
}
});
当您使用 lambda 表达式时,您实际上是在创建一个实现函数接口的匿名类的新实例。此实现的方法包含要运行的运行。
至于最后一个问题,它可能是正确的代码,但这是一个非常广泛的主题。
上一个:如何将子类转换为其父类?
评论
TestFunctionExecutor
TestClass test
foo:::bar
TestClass$$sampleFunction...
TestFunctionExecutor
public void wrapper(TestFunctionExecutor method)
TestFunctionExecutor
TestClass$$Lambda$1...
... implements TestFunctionExecutor
wrapper