繁体   English   中英

通用类型推断的奇怪问题

[英]strange issue with Generic type inference

我正在使用 Java8 的 Generics 有一个奇怪的行为。

这是一个演示问题的小示例代码以下代码可以正常工作,没有任何类型推断问题。 其中,SpecificError 是 GenericError 的子类型。

public GenericType<AbstractError> method{
   Optional<SpecificError> error = Optional.of(new SpecificError());
   if (error.isPresent()) {
    return GenericType.error(error.get());
  } else {
     // return something else
  }
}

我在代码中有很多这样的地方,如果/else 检查可选,我决定创建一个新的 function 接收可选,检查存在并返回通用类型 object 新 ZC1C4245268E617394F11 代码

public static <R extends AbstractError> GenericType<R> shortcut(Optional<R> error) {
    if (error.isPresent()) {
      return GenericType.error(error.get());
    } else {
    // something else
    }
}

这是调用上述 function 的新代码:

public GenericType<AbstractError> method{

       Optional<SpecificError> error = Optional.of(new SpecificError());
       return GenericType.shortcut(error);
    }

奇怪的是,这不起作用并破坏了以下编译错误:

[ERROR]     inferred: AbstractError

[ERROR]     equality constraints(s): AbstractError, SpecificError

我只是不明白,为什么这行不通。 唯一的事情,我做的是做一个小的function,它的工作是Present check on Optional,其他的都是一样的。 为什么 Java 看不到 SpecificError 是 AbstractError 的子类型

从方法method()中,您正在调用GenericType.shortcut(error) ,其中error的类型为Optional<SpecificError> shortcut需要一个类型参数R ,您正在尝试使用R = SpecificError来实现。 所以你试图返回一个GenericType<SpecificError> ,但你的方法签名声明它返回一个GenericType<AbstractError>

GenericType<SpecificError>不是GenericType<AbstractError> ,因为generics 是不变的

你可以通过更换来解决这个问题

Optional<SpecificError> error = Optional.of(new SpecificError());

Optional<AbstractError> error = Optional.of(new SpecificError());

当您在shortcut()处将 GenericType 声明为<R extends AbstractError>

它现在被迫返回一个子类型 这就是编译器产生问题的原因。

这里见证的概念是Type Equality Constraint ,涵盖在 Java Generics

如果您将方法签名更改为

public static <R> GenericType<R> shortcut(Optional<R> error) { // remove extends AbstractError
public GenericType<AbstractError> method{
   Optional<SpecificError> error = Optional.of(new SpecificError());
   return GenericType.shortcut(error);
}

public static <R extends AbstractError> GenericType<R> shortcut(Optional<R> error) {

shortcut需要一个Optional参数,其类型参数与返回类型匹配。

但你的不是: SpecificErrorAbstractError不同。

您只需要将error设为R或子类,因此为参数类型添加上限:

Optional<? extends R> error

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM