简体   繁体   English

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

[英]Why this enum doesn't compile?

Why this enum doesn't compile? 为什么这个枚举不能编译?

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
    }
}

That type argument is, as far as I know, not neccessary. 据我所知,那种类型的论证不是必要的。 Try simply 试试吧

public Ackr getInstance(){
    return INSTANCE;
}

What are you trying to achieve with this signature? 你想用这个签名来实现什么目标?

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

Can't you just write this? 你不能写这个吗?

public Ackr getInstance() ...

I also think that an enum that extends Clonable is kind of nonsensical. 我还认为扩展Clonableenum有点荒谬。 An enum cannot be copied ... there is only ever one of value of the enum. enum不能复制......枚举的价值只有一个。

I see that you have a misunderstanding about generics.. Enum class Ackr is not same with the type <Ackr extends Cloneable . 我看到你对泛型有一个误解。枚举类Ackr<Ackr extends Cloneable类型不一样。

public <Ackr extends Cloneable> Ackr getInstance()

You define a new type with with above method declaration. 使用上述方法声明定义新类型。 It is completely different than enum class Ackr. 它与枚举类Ackr完全不同。 That is why your class could not be compiled. 这就是为什么你的课无法编译的原因。

You wrote in a comment: 你在评论中写道:

I think there is no reason for <Ackr extends Cloneable> , but in which context this construct would make sense? 我认为没有理由<Ackr extends Cloneable> ,但在哪种情况下这个结构会有意义?

This is a type parameter for your method. 这是您方法的类型参数。

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

defines a method which returns an object of some type (electable by the caller) which extends Cloneable. 定义一个方法,该方法返回某种类型的对象(由调用者可选),该对象扩展了Cloneable。 This method could only legally return null (since you have no way to now which type the caller elected, and null is the only value common in all reference types) or throw an exception, thus it is not really useful. 此方法只能合法地返回null (因为您现在无法选择调用者选择哪种类型,并且null是所有引用类型中唯一的常用值)或抛出异常,因此它并不真正有用。

The type parameter Ackr here has no relation to your enum class of same name, so you would better write it like this: 这里的类型参数Ackr与同名的枚举类没有关系,所以你最好这样写:

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

There are some examples in the Java API which have such uses of type parameters only used in the return type - but then they return some parametrized type (and the type parameter of the method is used as a type parameter for the return type). Java API中有一些示例,它们仅使用返回类型中使用的类型参数 - 但随后它们返回一些参数化类型(并且该方法的类型参数用作返回类型的类型参数)。 Look for Collections.emptySet() , for example. 例如,查找Collections.emptySet()

More often, the type parameters of a method are used in the parameter types of the method (only or additional to return type). 更常见的是,方法的类型参数用于方法的参数类型(仅返回类型或附加类型)。

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

This method takes an Iterable of some type A, and returns an object of this type A. (From the name, one would suppose it takes the first element of this iterable.) Here is an implementation: 此方法采用某种类型A的Iterable,并返回此类型为A的对象。(从名称中,可以假设它采用此可迭代的第一个元素。)这是一个实现:

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

Generally: If you have a type parameter (anywhere), please make sure you don't name it the same as some existing type (like you did here) - it will shadow your existing type, leading to great confusion because of strange error messages like Ackr is not assignable to Ackr . 通常:如果你有一个类型参数(任何地方),请确保你没有将它命名为一些现有类型(就像你在这里做的那样) - 它会影响你现有的类型,由于奇怪的错误消息而导致很大的混乱像Ackr一样不能分配给Ackr

This is the reason type parameters often have one (or seldom two) character names like E (element-type), K , V (key and value type for maps), T (type in general). 这就是类型参数通常具有一个(或很少两个)字符名称的原因,如E (元素类型), KV (映射的键和值类型), T (通常为类型)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM