Java 将参数约束到公共(public)父类(super class)

标签 java generics type-parameter type-constraints

动机

我有一个 Either<L, R>类,表示两种类型之一的值,或语义不同的状态。在某些情况下,无论值是哪个备选方案,对其进行操作都是有值(value)的。

问题

我想要一个采用 Consumer<T> 的(非静态)方法, 其中TL 的父类(super class)型和 R , 其中LR是类的类型参数。
目前,java 让我这样做:(静态实现)

public static <T, L extends T, R extends T> void collapse(Either<L,R> e, Consumer<T> op)

当然,对于非静态实现,我不能对 L 施加约束。和 R ,因为它们已经为相关实例定义。我需要对 T 施加的那些约束相反,但 java 不允许我编写以下内容,因为它一次只允许父类(super class)型或子类型约束中的一个类。这尤其令人沮丧,因为所有类至少共享 Object作为常见的父类(super class)型,因此这些约束总是可满足的。

public void collapse(Consumer<? super L & R> op)

是否有任何其他方式来定义此约束,是否有任何暗示它在更高版本的 java 中被允许,或者是否有任何解释为什么它会成为一个破坏性功能?

最佳答案

在您的静态版本中,由于您需要消费者能够接受“L”或“R”类型,因此您实际上并不需要这些类型变量:Either<? extends T, ? extends T> e .

但除此之外,我想说您的静态版本确实是您能做的最好的。 Java 只是没有特别具有表现力的类型系统。

我不认为 Eran 的回答是一个特别好的解决方案(尊重),因为:

  1. 它对消费者产生了限制:你必须像你期望的那样使用一般的限制,除非你只使用 Object (宽泛得令人恼火),你总能找到一个你希望它稍微宽松一点的案例;
  2. 它引入了一个额外的类型参数任何地方你使用Either类型,即使您不需要使用消费者,因为您必须始终提供 3 个类型参数(即使它们是 ? )。第三种类型的参数感觉很笨拙。

我看到静态版本唯一真正的缺点是调用约定有点笨拙:Either.collapse(anEither, aConsumer)而不是 anEither.collapse(aConsumer) .当然,前者稍微更冗长……但它可以满足您的需求,因此您可能不得不接受这种尴尬。

关于Java 将参数约束到公共(public)父类(super class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56618413/

相关文章:

node.js - 如何输入自定义异步 Express 处理程序,以便透明地传递通用类型参数

Haskell - 限制数据参数

java - 如何从传入的扫描器中读取数组元素的值?

java - 在 mysql(或 JPA)中插入多行

java - 为什么我的 JPanel 在运行模拟时不更新?

java - 谷歌云应用程序引擎和本地主机上的 spring boot bug 使用应用程序引擎部署

ios - 数组扩展通用 Equatable - "Cannot invoke ' = =' with ..."

java - 具有泛型的订阅模型 - 实现多个泛型接口(interface)

c# - 如何使二进制乘法运算符 * 在泛型类中可用?

Java - 类型参数的最大数量