java - 泛型返回类型方法中的不兼容类型 (Java)

标签 java generics

从 C++ 转向 Java。具有通用返回类型的方法将无法编译。我认为这是因为我没有指定泛型方法的类型,但我什至不知道该怎么做。下面的代码无法编译:错误:不兼容的类型:AnInterface 无法转换为 I ... 其中 I 是类型变量:

在我看来,类型 I 确实看起来与 get 的返回类型兼容,因为我明确声明 I 扩展 AnInterface .

import java.util.*;

interface AnInterface {
  public int aMethod();
}

class AClass implements AnInterface {
  AClass() { l = new ArrayList<>(); }

  public int aMethod() { return 1; }
  public void add(AnInterface x) { l.add(x); }
  public AnInterface get() { return l.get(0); }

  // method on() will not compile
  public <I extends AnInterface> I on(int x) { I i = get(); return i; }

  List<AnInterface> l;
}

class BClass implements AnInterface {
  public int aMethod() { return 2; }
}

class Main
{
  public static void main(String[] args)
  {
    AClass a = new AClass(); 
    BClass b = new BClass();
    a.add(b);
    // How do I even call AClass::on()
    // BClass x = a.on<BClass>(); // I expect to call on() like this
  }
}

最佳答案

仔细看看方法on:

public <I extends AnInterface> I on() {
    I i = get(); 
    return i; 
}

使用I = BClass调用它意味着get()必须返回一个BClass。但是 get 的签名是 public AnInterface get(),这意味着我们只知道它返回一个 AnInterface 实现。它可以是一个 BClass,但也可以是任何其他实现 AnInterface 的东西。

您可以像这样更改on:

public AnInterface I on() {
    AnInterface i = get();
    return i;
}

签名现在显示 on 返回实现 AnInterface 的内容,这与我们从 get 返回的类型一致。

实际上你的例子已经清楚地说明了为什么你发布的代码无法输入检查。

AClass a = new AClass(); 
AClass b = new AClass();
a.add(b);
BClass c = a.<BClass>on();

我们期望对 on 的调用返回实例 b,因为这是添加到 a 的第一个元素。但b 的类型为AClass,而不是BClass。如果编译器不会拒绝该程序,我们将在 BClass 类型的变量 c 中拥有一个 AClass 实例。

关于java - 泛型返回类型方法中的不兼容类型 (Java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60565802/

相关文章:

java - 使用 JSch 将一个文件从远程计算机复制到另一台远程计算机

java - 当容器大小更改时,JTable 仅调整选定列的大小

Swift - 当可相等时比较泛型

java - 是否可以用 Java 构建通用表单

java - 如何根据构造函数值获取枚举实例并进行一般转换?

java - 渲染/更新线程同步

java - 捕获 lambda 表达式的池

java - 如何从类路径中的 Java 包中读取所有类?

c# - 泛型的泛型列表

java - 是否有一种类型可以保存 java 类的所有可能的 setter 引用,而不管所设置的类型如何?