在接受类的方法中使用枚举的接口方法

ayu*_*hgp 15 java enums

我有一个需要接受Enum类的方法.这些枚举实现了一个接口.现在我需要访问像ordinal(),name()等的Enum方法和我的接口方法.我尝试过的:

public <T extends ConfigFeature, Enum> void showEnabledFeatures(Class<T> enumType, long mask) {
    List<T> list = Arrays.asList(enumType.getEnumConstants());
    list.forEach(item -> {
        // My interface's method, works fine
        item.getMask();
        // Enum method doesn't work:
        // item.ordinal();
    });
}
Run Code Online (Sandbox Code Playgroud)

撤销订单会扭转工作:

public <T extends Enum, ConfigFeature> void showEnabledFeatures(Class<T> enumType, long mask) {
    List<T> list = Arrays.asList(enumType.getEnumConstants());
    list.forEach(item -> {
        // My interface's method, doesn't work now
        // item.getMask();
        // Enum method now works:
        item.ordinal();
    });
}
Run Code Online (Sandbox Code Playgroud)

有没有办法从接口和Enum访问这两种方法?

Swe*_*per 23

您使用错误的语法来表示T必须实现此接口并且是枚举.

这个:

<T extends ConfigFeature, Enum>
Run Code Online (Sandbox Code Playgroud)

不限制TEnum,但实际创建一个新的名为泛型参数Enum.

同样的,

<T extends Enum, ConfigFeature>
Run Code Online (Sandbox Code Playgroud)

没有制约TConfigFeature.您正在声明一个名为的新通用参数ConfigFeature.

正确的语法是使用&:

<T extends Enum<T> & ConfigFeature>
Run Code Online (Sandbox Code Playgroud)

请注意,订单在这里实际上很重要!Enum只能先来.

根据这里,只有第一个约束可以是一个类,然后它之后的所有约束都必须是接口:

TypeParameter:
    {TypeParameterModifier} Identifier [TypeBound]

TypeParameterModifier:
    Annotation

TypeBound:
    extends TypeVariable
    extends ClassOrInterfaceType {AdditionalBound}

AdditionalBound:
    & InterfaceType
Run Code Online (Sandbox Code Playgroud)

  • 最好将它改为`<T extends Enum <T>&MyInterface>`. (2认同)

Erw*_*idt 14

你的语法错了; 你需要:

public <T extends Enum<T> & ConfigFeature>
Run Code Online (Sandbox Code Playgroud)

您使用的语法创建了两个泛型类型参数,一个被调用T,一个被调用Enum(其中Enum没有界限,T有界扩展ConfigFeature).

请注意,为避免关于使用原始类型的任何泛型警告,您还必须为Enum绑定提供类型参数.一个名为Xalways 的枚举Enum<X>,因此您可以使用T extends Enum<T>,并且方法本地泛型声明的全文变为<T extends Enum<T> & ConfigFeature>


cpp*_*ner 6

,你的第二个例子替换&.&只要它们是第二种类型的接口,您就可以使用它来声明多个边界.如果使用逗号,则它是一个单独的类型参数,而不是绑定.