接口可以以某种方式阻止lambda表达式实现吗?

Mus*_*ful 8 java lambda

背景

我将以下接口作为API的一部分公开:

public interface Pasture {
    /**
     * @param t         The time of the visit (as measured from optimization starting point).
     * @param tLast     The time of the preceding visit (as measured from optimization starting point).
     * @return          The expected reward that will be reaped by visiting under the given conditions.
     */
    double yield(long t, long tLast);    
}
Run Code Online (Sandbox Code Playgroud)

客户端将"牧场"模型作为实现此接口的对象传递给我.每个物体代表一个牧场.

在API方面,我会在不同时间跟踪对这些对象的"访问",然后pasture.yield(time, lastVisitTime)在我需要知道牧场在平均时间内产生了多少时调用.

问题出现了,这个接口可以在客户端实现为lambda表达式,显然每个lambda表达式实例化都不一定会创建一个带有新标识的新对象,这是我依赖的,以便跟踪哪些牧场在什么时候被访问过.

有没有办法阻止接口实现为lambda表达式,而强制客户端将其实现为匿名类.当然,为它添加一个虚拟方法可以解决问题,但在我看来,这将是任意和不整洁的.还有另外一种方法吗?

Old*_*eon 5

这不是lambda边缘情况是你的问题.

假设同一个对象表示相同Pasture,因此使您的对象同时执行两项操作.这是一种代码味道,是造成困难的原因.

你应该强制你的Pasture对象实现类似的东西equals,然后你可以检查这些项是否相同.可悲的是,没有interface那样做,最近的是Comparable.

public interface Pasture extends Comparable<Pasture> {
Run Code Online (Sandbox Code Playgroud)

  • 确实,这击中了钉子.在合同中谈论"等于"使得开发人员敏锐地意识到需要提供适当实现的实例.它还明确表示`Pasture`实际上有_two_关注点,即使它在界面中只有一个自定义方法.您甚至可以在界面中添加"equals"并在那里对其进行适当的记录. (4认同)
  • @tennenrishin - 代码气味来自你的(错误的)假设,即如果两个对象**不相等,则它们是**不同的**对象.这是一个不安全的假设 - 在Java中你只能假设如果两个对象**相等(在`==`意义上)那么它们就是同一个对象.通过强制使用`equals`(如Marko建议)或`compareTo`,你执行合同而不是假设它. (2认同)
  • @MarkoTopolnik - 同意 - 遗憾的是,没有可执行的机制来确保对象正确地实现`equals`.`Comparable`不是完美的解决方案,但它比仅仅记录要求更好IMHO. (2认同)
  • 好吧,不要让我开始破坏`Comparable`实现:) _Nothing_可以在任何编程语言中强制执行正确性.如果牧场是无与伦比的,那么"可比较"就不是OP的问题. (2认同)