【问题标题】:Passing a void method with Callable using Java generics and Java 8 lambda使用 Java 泛型和 Java 8 lambda 通过 Callable 传递 void 方法
【发布时间】:2025-11-21 17:20:02
【问题描述】:

我正在尝试编写一个通用的性能日志记录函数,我可以将任何要计时的方法传递给该函数,并将执行时间记录到我的数据库中。我在大多数情况下都可以正常工作,但是在传递返回 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 方法上运行,还是我不走运?

【问题讨论】:

    标签: java generics lambda void


    【解决方案1】:

    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");
    

    【讨论】:

      【解决方案2】:

      Callables 必须返回一个值。

      void 说:它不返回值。

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

      【讨论】: