简体   繁体   中英

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. An enum cannot be copied ... there is only ever one of value of the enum.

I see that you have a misunderstanding about generics.. Enum class Ackr is not same with the type <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. 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?

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

The type parameter Ackr here has no relation to your enum class of same name, so you would better write it like this:

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). Look for Collections.emptySet() , for example.

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:

 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 .

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).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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