Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

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

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

@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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading