好的我目前正在定义泛型枚举参数如下:
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)
,有人可以向我解释如何正确地明确指定泛型实现给定的接口。
答案 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}}
获取值。