Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a void method with Callable using Java generics and Java 8 lambda

I'm attempting to write a generic performance logging function that I can pass any method to be timed into and it will log the execution time to my database. I have this working in most cases, but I get compiler errors when passing a method that returns void:

no instance(s) of type variable(s) T exist so that void conforms to T

Here is my class:

public class Performance {
    public static <T> T measureExecTime(Callable<T> c, String gid, String name) {
        T call = null;
        try {
            if (Constants.DEBUG) {
                Calendar start = Calendar.getInstance();
                call = c.call();
                Calendar end = Calendar.getInstance();
                long diff = end.getTimeInMillis() - start.getTimeInMillis();
                // log diff to database
            } else {
                call = c.call();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return call;
    }
}

And here is how I am calling it:

Performance.measureExecTime(() -> myMethod(myMethodParam1, myMethodParam2), "gid", "database_qualifier");

Is it possible for this functionality to behave on void methods, or am I out of luck?

like image 732
dadykhoff Avatar asked Sep 02 '16 18:09

dadykhoff


People also ask

How to pass arguments to Runnable and callable methods in Java 8?

In java 8 Runnable and Callable both interface have been annotated by @FunctionalInterface. We can implement run () and call () method using lambda expression. Here on this page we will also provide how to pass arguments to Runnable and Callable methods. Java 8 supports lambda expression.

How can we write callable as a lambda expression in Java?

How can we write Callable as a lambda expression in Java? A Callable interface defined in java.util.concurrent package. An object of Callable returns a computed result done by a thread in contrast to a Runnable interface that can only run the thread.

What is the use of callable object in Java?

The Callable object returns Future object that provides methods to monitor the progress of a task executed by a thread. An object of the Future used to check the status of a Callable interface and retrieves the result from Callable once the thread has done. In the below example, we can write a Callable interface as a Lambda Expression.

How to implement runnable and callable interface in Java 8?

In java 8 Runnable and Callable both interface have been annotated by @FunctionalInterface. We can implement run () and call () method using lambda expression.


1 Answers

Callable must have a return value. In this case you can simply return null, but you'll need a block lambda:

Performance.measureExecTime(() -> {
    myMethod(myMethodParam1, myMethodParam2);
    return null;
}, "gid", "database_qualifier");

If you want, you can create a helper method to make things a little cleaner:

static Callable<?> wrap(Runnable r) {
    return () -> {
        r.run();
        return null;
    };
}
// ...
Performance.measureExecTime(wrap(() -> myMethod(myMethodParam1, myMethodParam2)), "gid", "database_qualifier");
like image 102
shmosel Avatar answered Nov 14 '22 21:11

shmosel