访问实现接口的泛型枚举的父方法

时间:2014-06-30 03:29:37

标签: java generics interface enums

好的我目前正在定义泛型枚举参数如下:

public interface MyInterface
{
    public int GetValue ( );
}

public enum MyEnum implements MyInterface
{
    value1(1), value2(2);

    int myvalue;

    MyEnum ( int value )
    {
        this.myvalue = value;
    }

    public int GetValue ( )
    {
        return this.myvalue;
    }
}

public class PassGeneric
{
    public void AcceptsGeneric ( Enum<? extends MyInterface> generic_enum )
    {
        generic_enum.values();                                 // Not valid
        generic_enum.GetValue();                               // Not valid
        generic_enum.getDeclaringClass().getEnumConstants();   // Valid
        ((Enum<?>)generic_enum).values();                      // Not Valid
        ((MyInterface)generic_enum).GetValue();                // Valid
    }
}

我只是想了解为什么类型说明符Enum<? extends MyInterface>不允许我1)直接访问MyInterface方法,2)直接访问Enum方法,例如{{ 1}}。

转换适用于访问.values()方法,但对我来说,无法指定泛型类型扩展MyInterface,因为只更换MyInterface仍然合法Enum<? extends MyInterface>并将对象转换为Enum<?>

如果我误解了泛型的使用并实现(MyInterface),有人可以向我解释如何正确地明确指定泛型实现给定的接口。

2 个答案:

答案 0 :(得分:2)

您无法访问values(),因为它不是实例方法;它是属于枚举类型的静态方法。因此,传递超类Enum的实例并不能为您提供所需的信息。

就接口方法而言,声明Enum<? extends MyInterface>声明了关于 enum 的某些通用信息,但没有告诉编译器generic_enum本身就是一个实例MyInterface

如果您要声明generic_enum实施MyInterface,您应该这样做:

public void AcceptsGeneric ( MyInterface generic_enum )

如果出于某种原因,您需要知道它实现了MyInterface 它是一个枚举,您可以按如下方式声明您的方法:

public <T extends Enum<T> & MyInterface> void AcceptsGeneric ( T generic_enum )

答案 1 :(得分:0)

将方法的参数声明为Enum<? extends MyInterface> generic_enum限制了generic_enum的方法,您可以访问Enum而无需转换为Enum的方法。 type参数不会将类型更改为generic_enum.values(); generic_enum.GetValue(); ((Enum<?>)generic_enum).values(); // ((Enum<?>)generic_enum) still of type Enum 以外的其他类型。因此这些行无效:

((MyInterface)generic_enum).GetValue();

现在让我们看看以下一行:

Enum

没有理由不允许演员表演。扩展MyInterface的类可以实现ClassCastException。因此,没有理由不允许该演员。 (编译器不允许这样做,因为generic_enum.getDeclaringClass().getEnumConstants(); 可能在运行时发生。)

现在剩下的一行:

generic_enum

由于Enum<? extends MyInterface>的类型为generic_enum.getDeclaringClass(),因此Class<? extends MyInterface>的返回类型为Class。由于getEnumConstants()包含方法generic_enum,因此该行有效。

由于您仍然可以访问AcceptsGeneric类中的值,因此您可以将public void AcceptsGeneric(MyInterface generic_enum) 声明为

public<T extends Enum<T> & MyInterface> void AcceptsGeneric(T generic_enum)

generic_enum.getClass().getEnumConstants()

并使用

{{1}}

获取值。