EnumSet 作为通用接口中的参数
EnumSet as a parameter in generic Interface
我有一个用例:
inteface A{
get(EnumSet<?> fetchModes);
}
class B implements A{
//Here FetchMode is an enum
get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}
但是它抛出编译时错误:
Method get of class B has the same erasure as get(EnumSet fetchMode) of type A but doesn't override it.
我读到枚举不能通用,但有什么方法可以实现这个用例吗?
(基本上希望EnumSet是通用的,不同的实现可以传递不同的Enum)
尝试这个你必须使泛型类型扩展枚举:
public class B implements A<FetchMode> {
//Here FetchMode is an enum
public void get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}
}
interface A<T extends Enum<T>> {
void get(EnumSet<T> fetchModes);
}
如果参数类型完全匹配,一个方法可以覆盖另一个方法,但你的方法不匹配。尽管 EnumSet<FetchMode>
是 EnumSet<?>
的子类型,但它们并不完全相同。您没有在子 class 中覆盖超级 class 方法 get(EnumSet<?> fetchModes);
,而是用不同的参数类型重载它。当您检查或反编译 get(EnumSet fetchModes)
的字节码并且您的编译器开始抱怨时,由于擦除,这两个具有相同的签名。
这在 JLS §8.4.8.1 中有介绍:
A class cannot have two member methods with the same name and type
erasure
解决问题的一个天真的尝试是更改参数类型,使其与超级 class 的参数类型兼容,在子 class.[=18 中正确覆盖该方法=]
@Override
public void get(EnumSet<?> fetchModes) {
}
虽然这在某种程度上修复了编译器错误,但它仍然不够优雅,因为它允许您的 EnumSet 存储任何对象。但理想情况下,您可能希望它只存储枚举的某些子类型。这个成语支持这一点。
您需要做的是声明一个具有有界类型参数的通用接口,然后通过正确覆盖该方法来实现它,如下所示。
public interface A<E extends Enum<E>> {
void get(EnumSet<E> fetchModes);
}
public class B implements A<FetchMode> {
@Override
public void get(EnumSet<FetchMode> fetchModes) {
}
}
我有一个用例:
inteface A{
get(EnumSet<?> fetchModes);
}
class B implements A{
//Here FetchMode is an enum
get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}
但是它抛出编译时错误:
Method get of class B has the same erasure as get(EnumSet fetchMode) of type A but doesn't override it.
我读到枚举不能通用,但有什么方法可以实现这个用例吗? (基本上希望EnumSet是通用的,不同的实现可以传递不同的Enum)
尝试这个你必须使泛型类型扩展枚举:
public class B implements A<FetchMode> {
//Here FetchMode is an enum
public void get(EnumSet<FetchMode> fetchMode){
//Some logic here
}
}
}
interface A<T extends Enum<T>> {
void get(EnumSet<T> fetchModes);
}
如果参数类型完全匹配,一个方法可以覆盖另一个方法,但你的方法不匹配。尽管 EnumSet<FetchMode>
是 EnumSet<?>
的子类型,但它们并不完全相同。您没有在子 class 中覆盖超级 class 方法 get(EnumSet<?> fetchModes);
,而是用不同的参数类型重载它。当您检查或反编译 get(EnumSet fetchModes)
的字节码并且您的编译器开始抱怨时,由于擦除,这两个具有相同的签名。
这在 JLS §8.4.8.1 中有介绍:
A class cannot have two member methods with the same name and type erasure
解决问题的一个天真的尝试是更改参数类型,使其与超级 class 的参数类型兼容,在子 class.[=18 中正确覆盖该方法=]
@Override
public void get(EnumSet<?> fetchModes) {
}
虽然这在某种程度上修复了编译器错误,但它仍然不够优雅,因为它允许您的 EnumSet 存储任何对象。但理想情况下,您可能希望它只存储枚举的某些子类型。这个成语支持这一点。
您需要做的是声明一个具有有界类型参数的通用接口,然后通过正确覆盖该方法来实现它,如下所示。
public interface A<E extends Enum<E>> {
void get(EnumSet<E> fetchModes);
}
public class B implements A<FetchMode> {
@Override
public void get(EnumSet<FetchMode> fetchModes) {
}
}