【问题标题】:Java Generics Name Clash error when extending multiple interfaces扩展多个接口时出现 Java 泛型名称冲突错误
【发布时间】:2010-08-05 20:00:35
【问题描述】:

我已经查看了类似的问题,但提出了一些问题,所以就这样吧;

public interface Predicate<T>{
    boolean apply(T t);
}
public interface Function<F, T>{
    T apply(F f);
}

public class ConcretePredicate extends Predicate<Foo>, Function<Bar, Boolean>{
    @Override
    public boolean apply(Foo foo){/*stuff*/}
    @Override
    public Boolean apply(Bar bar){/*stuff*/}
} 

ConcretePredicate 显示错误,

“名称冲突:Predicate 类型的方法 apply(T) 与 Function 类型的 apply(F) 具有相同的擦除,但不会覆盖它”

看起来它应该可以工作,有人对发生了什么有任何想法吗?


[编辑] 所以看起来这是 eclipse 的问题,Galileo 没有显示这个错误,而 Helios 有。我已经用 eclipse 提交了一个错误报告,一旦我得到回复就​​会更新。

[编辑] 更改为更简单的情况,显示相同的错误但消除了有关擦除的混淆。

【问题讨论】:

  • 你用的是什么编译器?我无法复制。
  • 面向 Java 开发人员的 Eclipse IDE 1.3.0.20100617-0520 jdk1.0.6_13
  • apply(T t) 在运行时与apply(F f) 相同(泛型由编译器检查并转换为Object,并插入适当的强制转换)。不过,我目前无法进行测试,并且其他答案声称它有效,因此我无法给出明确的答案 - 请将此作为评论。
  • 真棒,真棒的问题。我很困惑,因为我到处都发现矛盾(例如bugs.sun.com/bugdatabase/view_bug.do?bug_id=6182950 中的代码对我来说编译得很好)。

标签: java generics


【解决方案1】:

代码确实有效。这里稍微改写为 ideone.com 的一类:

interface Predicate<T>{
    boolean apply(T t);
}
interface Function<F, T>{
    T apply(F f);
}
class Foo {}
class Bar {}
class Two<K, V>{
    private K k;
    private V v;
    public Two(K k, V v) {
        this.k = k;
        this.v = v;
    }
    public K getKey() {return k;}
    public V getValue() {return v;}
}

那么好东西来了:

abstract class NewPredicate
implements Predicate<Foo>, Function<Two<Foo, Bar>, Boolean>{
}

class ConcretePredicate extends NewPredicate{
    @Override
    public boolean apply(Foo foo){ return false; }
    @Override
    public Boolean apply(Two<Foo, Bar> two){ return null; }
} 

public class Main {
public static void main(String[] args) {
    System.out.println(new ConcretePredicate());
}
}

代码编译并运行良好(as seen on ideone.com、Eclipse 和javac 1.6.0_17)。


相关问题

这些与实际的“与...具有相同的擦除但不覆盖它”编译器错误消息有关:

【讨论】:

  • 那么为什么eclipse会给我这个错误呢?这只是 IDE 的问题吗?
  • @Andrew:您是说来自 ideone.com 的代码作为一个整体放入一个 Main 类中,不能在您的 Eclipse 中编译?哪个版本?
  • 我认为它应该编译,因为其中一个 apply 方法采用 Foo 参数,而另一个采用 Two
  • @polygenelubricants 也许我没有正确理解您,但是该错误报告中的情况和这里的情况完全不同。在错误报告中,这两种方法都采用具有相同擦除(List)的参数,在这种情况下,这两种方法采用完全不同类型的参数(FooTwo)。
【解决方案2】:

发生了什么是type erasure

要使其正常工作,您需要更改您的 apply 方法之一的名称。

【讨论】:

    【解决方案3】:

    我已向 eclipse 团队提交了一份错误报告,他们仍在争论 JLS 的语义及其含义,但看来我的问题确实是 eclipse Helios 中的错误。看起来我将不得不降级到伽利略,直到这个问题得到解决。

    Bugzilla Entry

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-22
      • 2021-10-09
      • 2012-10-17
      • 2017-08-27
      • 2019-09-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多