为什么这个枚举不能编译?

时间:2011-03-01 11:00:07

标签: java enums compiler-errors compiler-warnings

为什么这个枚举不能编译?

public enum Ackr implements Cloneable{
    INSTANCE;

    public <Ackr extends Cloneable> Ackr getInstance(){
        return INSTANCE; //Type mismatch: cannot convert from Ackr to Ackr
//      return (Ackr)INSTANCE; //Type safety: Unchecked cast from Ackr to Ackr
    }
}

4 个答案:

答案 0 :(得分:4)

据我所知,那种类型的论证不是必要的。试试吧

public Ackr getInstance(){
    return INSTANCE;
}

答案 1 :(得分:2)

你想用这个签名来实现什么目标?

public <Ackr extends Cloneable> Ackr getInstance() ...

你不能写这个吗?

public Ackr getInstance() ...

我还认为扩展enum的{​​{1}}有点荒谬。无法复制Clonable ...枚举的值只有一个。

答案 2 :(得分:2)

我发现你对泛型有误解。枚举类Ackr<Ackr extends Cloneable类型不一样。

public <Ackr extends Cloneable> Ackr getInstance()

使用上述方法声明定义新类型。它与枚举类Ackr完全不同。这就是为什么你的课无法编译的原因。

答案 3 :(得分:1)

您在评论中写道:

  

我认为<Ackr extends Cloneable>没有理由,但在哪种情况下这种结构会有意义?

这是您方法的类型参数。

public <Ackr extends Cloneable> Ackr getInstance(){ ... }

定义了一个方法,该方法返回某种类型的对象(可由调用者选择),该对象扩展了Cloneable。此方法只能合法地返回null(因为您现在无法选择调用者选择哪种类型,并且null是所有引用类型中唯一的常用值)或抛出异常,因此它不是非常有用。

这里的类型参数Ackr与你的同名枚举类没有关系,所以你最好这样写:

public <A extends Cloneable> A getInstance(){ ... }

Java API中有一些例子,它们只使用返回类型中使用的类型参数 - 但是它们会返回一些参数化类型(并且该方法的类型参数用作返回类型的类型参数)。例如,查找Collections.emptySet()

更常见的是,方法的类型参数用于方法的参数类型(仅返回类型或附加类型)。

 public <A> A getFirstElement(Iterable<A> list);

此方法采用某种类型A的Iterable,并返回此类型为A的对象。(从名称开始,可以假设它采用此可迭代的第一个元素。)这是一个实现:

 public <A> A getFirstElement(Iterable<A> list) {
     Iterator<A> it = list.iterator();
     if(it.hasNext()) {
         return it.next();
     }
     return null;
 }

通常:如果您有一个类型参数(任何地方),请确保您没有将其命名为某些现有类型(就像您在此处所做的那样) - 它会影响您现有的类型由于奇怪的错误信息,如 Ackr无法分配给Ackr ,导致极大的混乱。

这就是类型参数通常有一个(或很少两个)字符名称的原因,如E(元素类型),KV(地图的键和值类型) ,T(一般输入)。