正如本网站上的另一个问题所述,这样的事情是不合法的:
public enum MyEnum {
FOO {
public Integer doSomething() { return (Integer) super.doSomething(); }
},
BAR {
public String doSomething() { return (String) super.doSomething(); }
};
public Object doSomething();
}
这是由于covariant返回类型显然不适用于枚举常量(再次打破了enum常量是枚举类型的单例子类的错觉......)那么,我们如何添加一些泛型:这是合法的吗?
public enum MyEnum2 {
FOO {
public Class<Integer> doSomething() { return Integer.class; }
},
BAR {
public Class<String> doSomething() { return String.class; }
};
public Class<?> doSomething();
}
这里,所有三个返回Class
个对象,但各个常量比整个枚举类型“更具体”......
答案 0 :(得分:4)
从根本上说,问题是MyEnum.FOO
的编译时类型是MyEnum
,不是特定生成的子类。您可以在没有任何协方差的情况下看到这一点:
enum MyEnum {
FOO {
public void foo() {}
};
}
public class Test {
public static void main(String[] args) throws Exception
{
MyEnum.FOO.foo(); // Error
}
}
基本上,编译器只会 查看MyEnum
中声明的签名。
答案 1 :(得分:1)
我们可以在Java枚举中使用Covariant返回类型,但我们不能将该子类型用于分配返回的变量,这与普通的类层次结构不同。
public class EnumCovariance {
public static void main(String[] args) {
// Type mismatch: cannot convert from Class<capture#1-of ?> to Class<Integer>
Class<Integer> something = MyEnum2.FOO.doSomething();
Child child = new Child();
Base base = child;
// ok
Class<Integer> something3 = child.doSomething();
// Type mismatch: cannot convert from Class<capture#2-of ?> to Class<Integer>
Class<Integer> something2 = base.doSomething();
}
}
abstract class Base {
public abstract Class<?> doSomething();
}
class Child extends Base {
@Override
public Class<Integer> doSomething() {
return Integer.class;
}
}
enum MyEnum2 {
FOO {
public Class<Integer> doSomething() {
return Integer.class;
}
},
BAR {
public Class<String> doSomething() {
return String.class;
}
};
public abstract Class<?> doSomething();
}
答案 2 :(得分:0)
此代码效果很好:
public enum MyEnum {
FOO {
@Override
public Integer doSomething() {
return (Integer)super.doSomething();
}
},
BAR {
@Override
public String doSomething() {
return (String)super.doSomething();
}
};
public Object doSomething() {
System.err.println( this );
return null;
}
public static void main( String[] args ) {
MyEnum toto = MyEnum.FOO;
System.err.println( toto.doSomething() );
}
}
输出是:
FOO
null
此代码无法编译,错误为"The return type is incompatible with MyEnum2.doSomething()"
,Cannot cast from Class<Object> to Class<Integer>
和Cannot cast from Class<Object> to Class<String>
:
public enum MyEnum2 {
FOO {
@Override
public Class<Integer> doSomething() {
return (Class<Integer>)super.doSomething();
}
},
BAR {
@Override
public Class<String> doSomething() {
return (Class<String>)super.doSomething();
}
};
public Class<Object> doSomething() {
System.err.println( this );
return null;
}
public static void main( String[] args ) {
MyEnum2 toto = MyEnum2.FOO;
System.err.println( toto.doSomething() );
}
}