gpt4 book ai didi

java - 如何在单个约束中同时使用方法和类类型参数?

转载 作者:搜寻专家 更新时间:2023-10-30 21:29:14 25 4
gpt4 key购买 nike

我将尝试在以下简化示例中说明我的问题:

public class DataHolder<T> {
private final T myValue;

public DataHolder(T value) {
myValue = value;
}

public T get() {
return myValue;
}

// Won't compile
public <R> DataHolder<R super T> firstNotNull(DataHolder<? extends R> other) {
return new DataHolder<R>(myValue != null ? myValue : other.myValue); }

public static <R> DataHolder<R> selectFirstNotNull(DataHolder<? extends R> first,
DataHolder<? extends R> second) {
return new DataHolder<R>(first.myValue != null ? first.myValue : second.myValue);
}
}

在这里,我想编写返回 DataHolder 的通用方法 firstNotNull,该方法由 thisother 参数,所以稍后我可以写例如

DataHolder<Number> r = new DataHolder<>(3).firstNotNull(new DataHolder<>(2.0));

DataHolder<Object> r = new DataHolder<>("foo").firstNotNull(new DataHolder<>(42));

问题是 firstNotNull 的这个定义被编译器拒绝,消息是类型约束的 super T 部分是非法的(语法上)。然而,没有这个约束定义也是错误的(很明显),因为在这种情况下 TR 彼此无关。

有趣的是,类似静态方法 selectFirstNotNull 的定义是正确的,后者按预期工作。是否有可能在 Java 类型系统中使用非静态方法实现同样的灵 active ?

最佳答案

这是不可能的。 Guava 的作者遇到与 Optional.or 相同的问题.从该方法的文档中:

Note about generics: The signature public T or(T defaultValue) is overly restrictive. However, the ideal signature, public <S super T> S or(S), is not legal Java. As a result, some sensible operations involving subtypes are compile errors:

Optional<Integer> optionalInt = getSomeOptionalInt();
Number value = optionalInt.or(0.5); // error

FluentIterable<? extends Number> numbers = getSomeNumbers();
Optional<? extends Number> first = numbers.first();
Number value = first.or(0.5); // error

As a workaround, it is always safe to cast an Optional<? extends T> to Optional<T>. Casting either of the above example Optional instances to Optional<Number> (where Number is the desired output type) solves the problem:

Optional<Number> optionalInt = (Optional) getSomeOptionalInt();   
Number value = optionalInt.or(0.5); // fine

FluentIterable<? extends Number> numbers = getSomeNumbers();
Optional<Number> first = (Optional) numbers.first();
Number value = first.or(0.5); // fine

DataHolderOptional 一样是不可变的,上述解决方法也适用于您。

另请参阅:Rotsor's answer to Bounding generics with 'super' keyword

关于java - 如何在单个约束中同时使用方法和类类型参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28947416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com