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?
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? 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.
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.
In java 8 Runnable and Callable both interface have been annotated by @FunctionalInterface. We can implement run () and call () method using lambda expression.
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");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With