代码之家  ›  专栏  ›  技术社区  ›  Dale Wijnand

无法编译实现没有类型参数的接口的类

  •  6
  • Dale Wijnand  · 技术社区  · 16 年前

    我有以下测试代码:

    public interface Container<I> {
        public void addClass(Class<?> clazz);
    }
    
    public class MyContainer implements Container {
        public void addClass(Class<?> clazz) {}
    }
    

    MyContainer.java公司:1:MyContainer不是抽象的,并且不重写抽象方法addClass(java.lang.Class)集装箱内

    如果我在MyContainer中向容器接口添加类型(例如 <Object> ),我不明白错误。

    有人有什么想法吗?这是类型擦除问题吗?有解决办法吗?

    4 回复  |  直到 12 年前
        1
  •  7
  •   Jon Skeet    16 年前

    我认为问题是如果你在类声明中的任何地方使用原始类型,你就有点不选择泛型。所以这是可行的-注意参数的变化。

    public class MyContainer implements Container {
        public void addClass(Class clazz) {}
    }
    

    从 section 4.8 of the JLS

    超类(分别是, 删除超类 参数化调用。

    我 相信 这是相关的一点。。。抹去 Container<T>.addClass(Class<?> clazz) 是 addClass(Class clazz) .

        2
  •  3
  •   Bozho    16 年前

    如果 <?> 修复它:

    public void addClass(Class clazz) {}
    

    错误消息的描述性不强:

    名称冲突:MyContainer类型的addClass(Class)方法与Container类型的addClass(Class)具有相同的擦除,但不会重写它

    这意味着当删除类型时,这两个方法是相同的,但是子类方法实际上并没有实现/重写超类/接口中的方法。这没有多大意义,我会假设这是因为你选择了不在你的子类中使用泛型,你必须坚持这一点(而不是过量化) Class )

        3
  •  3
  •   Colin Hebert    16 年前

    如果您的类使用泛型,那么一个简单的解决方案是:

    interface Container<I> {
        public void addClass(Class<?> clazz);
    }
    
    class MyContainer<I> implements Container<I> {
        public void addClass(Class<?> clazz) {}
    }
    

    或者你已经知道集装箱的类型,

    class MyContainer implements Container<ContainerType> {
        public void addClass(Class<?> clazz) {}
    }
    

    如果你的类不使用泛型(1.5之前的版本),那么你就不能 <?>

    class MyContainer implements Container {
        public void addClass(Class clazz) {}
    }
    
        4
  •  0
  •   Faisal Feroz    16 年前

    按照以下方式实现接口应该可以工作(根据类型擦除):

    public class MyContainer implements Container {
        public void addClass(Class clazz) {}
    }