【发布时间】:2015-08-18 08:27:43
【问题描述】:
背景
我将以下接口作为 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);
}
客户端将“牧场”模型作为实现此接口的对象传递给我。每个对象代表一个牧场。
在 API 方面,我会在不同时间跟踪对这些对象的“访问”,然后在需要知道牧场同时生产多少时调用 pasture.yield(time, lastVisitTime)。
问题出现了,这个接口可以在客户端实现为 lambda 表达式,而 apparently each lambda expression instantiation does not necessarily create a new object with a new identity,这是我用来跟踪在什么时间访问了哪些牧场的方法。
问题
有没有办法阻止接口被实现为 lambda 表达式,而是强制客户端将其实现为匿名类。当然,向它添加一个虚拟方法可以解决问题,但在我看来,这将是任意且不整洁的。还有其他方法吗?
【问题讨论】:
-
你不能检测到重复的牧场通过并适当地处理它吗?注意:使用匿名内部类确实保证每次都会创建一个新的。
-
^ 这个:lambda 和匿名类的区别主要是在这方面的语法。也许您需要更高抽象级别的另一种方法(也许“Pasture”作为一个抽象类,只能通过工厂左右实例化,但对于具体提示,缺少有关意图使用的详细信息......)
-
什么会阻止您的客户将
Pasture的单个实例保存在静态/实例变量中并重用它? Java 编译器在对 lambda 进行脱糖时会执行完全相同的操作。 -
那么您的客户必须注意遵守合同,无论是使用 lambda 表达式还是任何其他方式来实现接口。关键是 lambdas 对你来说不是一个特例。
-
在Java中很简单:你申请
new,你得到一个新的实例;您不应用它-> 不保证。每个 Java 开发人员都应该意识到这一点。 Lambda 没有什么特别之处,它们只是另一种表达方式。普通的 Java 开发人员是否期望(Integer) 3总是返回Integer的新实例?我希望不会,而且肯定是开发人员有责任知道这一点。