How does java differentiate Callable and Runnable

2020-07-07 03:13发布

I got this little code to test out Callable. However, I find it pretty confusing how the Compiler could know if the Lambda is for the Interface Callable or Runnable since both don't have any parameter in their function.

IntelliJ, however, shows that the Lambda employs the code for a Callable.

public class App {
    public static void main(String[] args) throws InterruptedException {
        ExecutorService executorService = Executors.newCachedThreadPool();
        executorService.submit(() ->{
            System.out.println("Starting");
            int n = new Random().nextInt(4000);
            try {
                Thread.sleep(n);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }finally {
                System.out.println("Finished");
            }
            return n;
        });
        executorService.shutdown();
        executorService.awaitTermination(1, TimeUnit.MINUTES );
    }
}

2条回答
老娘就宠你
2楼-- · 2020-07-07 03:51

The main difference in the signature is that a Callable returns a value while a Runnabledoes not. So this example in your code is a Callable, but definately not a Runnable, since it returns a value.

查看更多
做个烂人
3楼-- · 2020-07-07 03:52

See the documentation of ExecutorService which has 2 submit methods with one parameter:

Your lambda gives an output, returns something:

executorService.submit(() -> {
    System.out.println("Starting");
    int n = new Random().nextInt(4000);
    // try-catch-finally omitted
    return n;                                      // <-- HERE IT RETURNS N
});

So the lambda must be Callable<Integer> which is a shortcut for:

executorService.submit(new Callable<Integer>() {
    @Override
    public Integer call() throws Exception {
        System.out.println("Starting");
        int n = new Random().nextInt(4000);
        // try-catch-finally omitted
        return n;  
    }}
);

To compare, try the same with Runnable and you see it's method's return type is void.

executorService.submit(new Runnable() {
    @Override
    public void run() {
        // ...  
    }}
);
查看更多
登录 后发表回答