我有一个Either<L, R>
类,它表示两种类型之一或语义上不同的状态的值。在某些情况下,无论值是哪种替代方案,对其进行操作都是有价值的。
我想要一个采用Consumer<T>
的(非静态)方法,其中T
是L
和R
的超类型,其中L
和R
是该类的类型参数。
目前,java允许我执行以下操作:(静态实现)
public static <T, L extends T, R extends T> void collapse(Either<L,R> e, Consumer<T> op)
但是,当然,对于非静态实现,我无法对L
和R
施加约束,因为已经为相关实例定义了约束。我需要施加在T
上的那些约束,但是Java不允许我写以下内容,因为它一次只允许一个类在超类型或子类型约束中。鉴于所有类都至少共享Object
作为一个公共超类型,这尤其令人沮丧,因此这些约束始终可以满足。
public void collapse(Consumer<? super L & R> op)
是否还有其他方法可以定义此约束,在更高版本的Java中允许使用此约束的任何提示,或者对为什么它将成为破坏性功能的任何解释?
答案 0 :(得分:4)
在静态版本中,由于您需要使用者能够接受“ L”或“ R”类型,因此实际上并不需要这些类型变量:Either<? extends T, ? extends T> e
。
但是除此之外,我想说的是静态版本确实是您可以做的最好的事情。 Java只是没有特别具有表现力的类型系统。
我不认为伊兰(Eran)的回答是一个很好的解决方案,因为:
Object
(令人讨厌的范围),否则您总是会发现以下情况:您希望它只允许一点点; Either
类型,因为您必须始终提供3个类型参数(即使如果它们是?
)。第三种类型的参数感觉就像cru脚。我看到的静态版本唯一真正的缺点是调用约定:Either.collapse(anEither, aConsumer)
,而不是anEither.collapse(aConsumer)
。当然,前者稍微有些冗长...但是它可以满足您的要求,因此您可能只需要接受尴尬即可。
答案 1 :(得分:2)
也许您应该添加T
作为类的第三个类型参数:
class Either<T, L extends T, R extends T>
{
public void collapse(Consumer<T> op) {
}
}