I wrote the following Java code and expected it to not compile but it did and also executed counterintuitively. I am using 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");
}
}
Output -
Before method execution
Inside sampleFunction
After method execution
I thought since wrapper
expects an argument of type TestFunctionExecutor
and I am passing one of type TestClass
the compilation should fail. I used a debugger and looks like method
is a TestClass$$Lambda$1...
at runtime. This confuses me and I have a few questions -
test::SampleFunction
? Is it not TestClass
or something like TestClass$$sampleFunction...
? I am unable to deduce this with a debugger.execute
know what code to execute?Thanks!
In Java, lambda expressions are just a sugar syntax for something called Anonymous class, which are basically classes created on the spot with a name created by the JVM.
Your code can be equally written in 4 ways (from more concise to less concise) :
test.wrapper(test::sampleFunction);
test.wrapper(() -> test.sampleFunction());
test.wrapper(() -> {
test.sampleFunction();
});
test.wrapper(new TestFunctionExecutor() {
public void execute() {
test.sampleFunction();
}
});
When you use a lambda expression, you actually create a new instance of an anonymous class that implements the functional interface. And the method of this implementation contains the run you want to run.
As for the last question, it might be correct code, but this is a very broad topic that depends.