【问题标题】:Function Pointers as Parameters in Java 8Java 8 中作为参数的函数指针
【发布时间】:2016-01-20 07:51:37
【问题描述】:

为了减少 JPA 中属性每次更新的代码重复,我想将一个函数指针交给doTransaction 并调用该函数。我如何在 Java 8 中做到这一点?

public void modifySalary(Person person, float salary) {
    doTransaction(person.setSalary(salary));
}

public void doTransaction(final Function<Void, Void> func) {
    em.getTransaction().begin();
    func.apply(null);
    em.getTransaction().commit();
}

【问题讨论】:

    标签: java jpa java-8


    【解决方案1】:

    您可以接受Runnable 作为doTransaction 的参数,并将其传递给更新人员的lambda 表达式。这里,我们只使用Runnable作为函数式接口,定义了一个不带参数不返回值的方法。

    public void modifySalary(Person person, float salary) {
        doTransaction(() -> person.setSalary(salary));
    }
    
    public void doTransaction(Runnable action) {
        em.getTransaction().begin();
        action.run();
        em.getTransaction().commit();
    }
    

    如果您认为 Runnable 这个名称与线程的联系过于紧密,您可以推出自己的接口,定义一个不带参数且不返回值的函数式方法。例如,如果你想将它命名为Action,你可以有

    @FunctionalInterface
    interface Action {
        void perform();
    }
    

    然后在doTransaction 中调用action.perform()

    【讨论】:

    • 我知道它与线程有关。但它无需定义我自己的@FunctionInterface 即可工作。有什么想法吗?
    • @msch 实际上,这就是我要表达的意思。在这种情况下,我们只是使用它,因为它是一个现有的不带参数也不返回值的功能接口。没有任何与线程的真正链接。我的回答的第二部分只是提供一个替代名称。
    • Runnable 未链接到线程。 API 设计者故意决定不在java.util.function 包中包含void noarg 函数,因为已经存在的类型Runnable 满足了这一要求。
    • @Holger 不知道,你有这个链接吗?我有兴趣了解为什么故意这样做。
    • Here Brian Goetz 在 cmets 中证实了这一点。
    【解决方案2】:

    在这种情况下,您需要一个无参数的 void 函数,Runnable 就足够了。

    public void modifySalary(Person person, float salary) {
      doTransaction(()->person.setSalary(salary));
    }
    
    public void doTransaction(Ruunable runnable) {
        em.getTransaction().begin();
        runnable.run();
        em.getTransaction().commit();
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-29
      • 2011-02-04
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2012-02-26
      相关资源
      最近更新 更多