为什么这个枚举不能编译?
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
}
}
答案 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
(元素类型),K
,V
(地图的键和值类型) ,T
(一般输入)。