通过交集类型具有附加约束的通用参数

时间:2017-10-24 13:54:14

标签: java generics

我正在编写一个表示时间序列数据的类,即基本上是泛型类型(Instant, T)的{​​{1}}对映射

T

我们处理的一些类实现了一个接口

interface TimeSeries<T> {
     void add(Instant when, T data);
}

我希望在interface TimeStamped { Instant getTimeStamp(); } 界面中提供一个更方便的方法来添加此类数据项,而无需说明时间。基本上,我想要

TimeSeries

but this seems not allowed by the language because I cannot use type variables in intersection types。是否存在不涉及放弃静态类型安全的解决方法?我能想到的唯一的事情是

interface TimeSeries<T> {
     void add(Instant when, T data);
     default <X extends T & TimeStamped> void add(X data) {
         add(data.getTimeStamp(), data);   
     } 
}

interface TimeSeries<T> { void add(Instant when, T data); default void add(TimeStamped data) { add(data.getTimeStamp(), (T)data); } default void add(TimeStamped t, T data) { add(t.getTimeStamp(), data); } } 类型安全,但仍然不方便。

1 个答案:

答案 0 :(得分:1)

我想我理解你的问题。基本上,你可以使用TimeSeries一些简单的类型来实现TimeStamped,但是它的一些子类可以实现。{1}}。在这些情况下,甚至@assylias的解决方法都没有帮助。

好吧,我认为在Java 8中没有针对这个问题的干净解决方案,而且我没有使用Java 9的经验,但在阅读其新功能时我没有注意到这一点。这意味着你要么牺牲静态类型的安全性,要么安慰。

很难说什么是最好的解决方法。基本上我们到目前为止所拥有的是:

  • 基于TimeStamped的接口,用于基础对象已实现TimeStamped接口的情况,如@assylias所建议。
  • @cppbeginner建议的静态方法。我不喜欢这种语法,它的意思是语法糖,但你最终会得到静态调用。它虽然功能多样,却可以满足您的需求。
  • 完全放弃语法糖的想法,只需输入它就像奴隶一样。
  • 放弃类型安全并拥有可以适得其反的好代码。
  • 哦等等,还有一种可能性。将其作为TimeStamped接口的方法,而TimeSeries作为参数。实际上比静止更好,但有点自下而上。

我无法确定哪一个更适合您,因为我不了解您的使用案例。它们都不是完美的。我已经遇到过这个问题,我也没有找到超级智能解决方案。我无法做的另一件事是通用枚举。我的意思是,为什么不呢,如果可能的话会很有意思(但它也不是)。