当前位置: 首页 > 知识库问答 >
问题:

Java 8泛型方法...不适用于Eclipse中的参数

燕智
2023-03-14

在我们的代码库从java 1.7迁移到1.8的过程中,我们得到了一个错误消息“方法...不适用于几个代码位置上的参数,它们都遵循泛型用法中的相同模式。

我们目前主要在Windows 7上使用Eclipse Mars(4.5.2),但也可以使用Neon(4.6)确认行为。Javac以及符合级别为1.7的ecj都可以编译我们的代码而不会出错。

下面是一个最小、完整且可验证的示例

public class ComplexInterfaceTest {

  public static class Foo {}

  public interface Bar {
    void print();
  }

  public static class SubFooBar extends Foo implements Bar {
    public void print() {
      System.out.println(this.getClass().getSimpleName());
    }
  }

  public static class FooBar<T extends Foo & Bar> {
    public static <T extends Foo & Bar> FooBar<T> makeFooBar() {
      return new FooBar<>();
    }

    public void create(T value) {
      value.print();
      return;
    }
  }

  public static class Base<T extends Foo> {}

  public static class Subclass extends Base<SubFooBar> {
    public void doSomething(SubFooBar value) {
//      FooBar.<SubFooBar>makeFooBar().create(value);
      FooBar.makeFooBar().create(value);
    }
  }

  public static void main(String[] args) {
    new Subclass().doSomething(new SubFooBar());
  }

}

现在,在 do 中切换注释掉的行某些方法会使代码编译,因此我们确实有一个解决方法。仍然错误消息似乎不正确,因为类子FooBar扩展了Foo并实现了Bar,因此它履行了

我搜索了类似的问题,发现了这些:类型推断JDK8 javac/Eclipse Luna的差异?使用Java8但不使用Java7的Eclipse中的类型推断编译器错误

这让我觉得这可能是一个< code>ecj错误。在本课程中,我还研究了< code>Eclipse Bugzilla,但找不到任何类似的内容,我看到了以下内容:

  • 430686已验证固定-我的不是
  • 440019与标量类型有关-我的不是
  • 492838,448793与通配符有关-我的不是

现在,Eclipse Bugzilla讨论中充满了关于ecj内部工作的细节,我并不总是能理解这些细节。但我所理解的是,那里的普遍共识是,Eclipse编译器必须严格遵循JLS,而不是javac(在出现错误的情况下),所以它不一定是 中的bug。如果它不是一个 ecjbug,那么编译代码一定是一个 javacbug。

我感兴趣的是——对于那些可以分析我的代码片段的类型推理过程的人来说——代码应该已经编译过了,还是我在编码中犯了错误?

编辑

正如我promise将我的报告结果发布到Eclipse的Bugzilla:该缺陷的ID为#497905(Stephan Herrmann已在接受的答案下方的评论中发布了链接),目前针对v4.7。

共有1个答案

酆景辉
2023-03-14

在该方法中

public void doSomething(SubFooBar value) {
  FooBar.makeFooBar().create(value);
}

方法< code>makeFooBar()的类型参数< code>T永远不会被推断为< code>SubFooBar。事实上,您将随后将< code>SubFooBar的实例传递给< code>create方法,这不会影响前面的调用表达式< code>FooBar.makeFooBar()的类型。

Java不会改变这一点

因此,在所有版本中,为makeFooBar()调用的T>推断的类型将是交叉类型

这意味着您可以将SubFooBar实例作为传递给create方法FooBar

可以证明 Eclipse 确实推断出与所有其他编译器相同的类型,就像插入适当的类型强制转换一样

public void doSomething(SubFooBar value) {
  FooBar.makeFooBar().create((Foo&Bar)value);
}

使编译器错误消失。所以这里的问题不是类型推断,而是这个Eclipse版本认为< code>SubFooBar不可分配给< code>Foo

 类似资料:
  • 我试图在一个测试中模拟。我在网上找到了一些人们也这么做的例子。 一个例子来自sping-data-elasticsearch,另一个来自一些教程。 这是我自己的例子。 不幸的是,我看到了一些警告。以下是我得到的: 网络客户。RequestHeaderUrispec是原始类型。对泛型类型WebClient的引用。RequestHeaderUrispec应该参数化 当我更改代码并向添加通配符时,我会收

  • 我的代码中有这个错误,我是一个初学者,我不知道为什么在其他程序中,点击时执行的动作事件/动作是成功的,但在这个程序中,我使用了相同的模式,它给了我这个错误,有人能帮助我吗? 当我尝试在用户单击login时放置事件时,错误通过createfirstframe类发生 这是我的课程表 多谢

  • 我已经尝试了网络上提供的所有解决方案,但都无效。请尽快提供帮助。同步错误: 生成文件“C:\Users\AH\U GL\Desktop\apps android commons\apps\Build”。格拉德尔线:149 评估项目“:app”时出现问题。 没有方法的签名:build_bacf6ncg9oj63qiyhi1id1rfi.android()适用于参数类型:(build_bacf6ncg

  • 嗨,我在GAE中的JSP代码面临一个名为“JspWriter类型中的方法print(boolean)不适用于参数(val)”的错误。 在线:

  • 我想在主类中添加一个功能齐全的按钮 我有一个错误:类型AbstractButton中的方法addActionListener(ActionListener)不适用于参数(JPanel) (我试着把杰帕内尔作为论据)

  • 我试图在Apache POI中使用自定义颜色,但遇到了一个小问题。到目前为止,我一直在使用,但作为调色板,它非常单调。因此,使用RGB格式进行颜色选择将有助于我的电子表格看起来更好。 我一直在使用这个问题的答案,因为它从理论上解决了我的问题。然而,我面临着一个非常愚蠢的问题,我真的不知道如何解决。 我收到的错误是: 类型CellStyle中的setFillForegroundColor(short