使用Java泛型和Java 8 lambda使用Callable传递void方法

时间:2016-09-02 18:32:55

标签: java generics lambda void

我试图编写一个通用的性能日志记录函数,我可以传递任何方法来定时,它会将执行时间记录到我的数据库中。我在大多数情况下使用它,但在传递返回void的方法时出现编译器错误:

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

这是我的班级:

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;
    }
}

以下是我的称呼方式:

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

此功能是否可以在void方法上运行,或者我运气不好?

2 个答案:

答案 0 :(得分:8)

Callable必须有返回值。在这种情况下,您只需返回null,但您需要一个块lambda:

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

如果需要,可以创建一个辅助方法,使事情变得更清洁:

static Callable<?> wrap(Runnable r) {
    return () -> {
        r.run();
        return null;
    };
}
// ...
Performance.measureExecTime(wrap(() -> myMethod(myMethodParam1, myMethodParam2)), "gid", "database_qualifier");

答案 1 :(得分:0)

Callables必须返回一个值。

void 说:它不会返回值。

因此,很难解决这两个相互冲突的目标!