How does Java handle private methods being passed as Runnables to a separate service class in a Spring Boot application?

Advertisements

I have a Spring Boot test class where I’ve defined a private method. I also have a helper Service class which has a simple method that accepts a Runnable and executes it.

My expectation was that the private method from the test class could not be passed and run as a Runnable in the Service class because it’s private. However, in practice, the method seems to be running without any issues.

Here’s a simplified example of what I’m doing:

@SpringBootTest  
public class MyTest {  
    private void myPrivateMethod() {  
        // Some code here  
    }  
  
    @Autowired  
    private MyService myService;  
  
    @Test  
    public void myTest() {  
        myService.runRunnable(() -> myPrivateMethod());  
    }  
}  
  
@Service  
public class MyService {  
    public void runRunnable(Runnable r) {  
        r.run();  
    }  
}  

I’m confused as to why this works. I thought that private methods could not be accessed outside of the class they’re defined in. Could anyone explain why this is possible?

>Solution :

You are not passing a private method.

In fact in Java you can’t pass around methods at all*.

You’re passing around an implementation of Runnable.

That implementation is created via () -> myPrivateMethod(). This is a simple way to define some code to implement a functional interface (like Runnable).

The myPrivateMethod() here is just a boring old method call. You define some code, that happens to call a private method. Since the method call is allowed in this place, you can create a Runnable that does this.

The code you showed is roughly equivalent to this:

myService.runRunnable(new Runnable() {
  public void run() {
    myPrivateMethod();
  }
})

which creates an anonymous inner class. While using the lambda expression above doesn’t necessarily create a class, it’s functionally equivalent to this code.

* you might find code that looks like it’s passing around methods, but it’s always just creating implementations of interfaces that call those methods in one way or another.

Leave a ReplyCancel reply