问题1:我对这些代码有点困惑:
public class MyClass1 <E extends Enum<?>> {
// ...
}
public class MyClass2 <E extends Enum<E>> {
// ...
}MyClass1和MyClass2的区别是什么,这三种不同的E意味着什么?
问题2:来自Class Enum >
这是所有Java语言枚举类型的公共基类。
但是不是所有Enum类型的Enum<E>的公共基类吗?
问题3:现在我有一节课:
public class MyClass<E extends Enum<E>> {
// for example, EnumSet<Category>
public Set<E> category;
// how to initial this member
private Class<E> enumType;
// initial this.category with given strings
public void getEnumSetFromStringList(List<String> list) {
this.category = EnumSet.noneOf(enumType);
for (String str : list) {
this.category.add(Enum.valueOf(this.enumType, str));
}
}
}
// this is the Category of Enum type
public enum Category {
LOCATION("LOCATION"),
HUMAN("HUMAN"),
// ...
DESCRIPTION("DESCRIPTION");
private final String categoryName;
Category(String categoryName) {
this.categoryName= categoryName;
}
}enumType中用MyClass初始化数据字段MyClass不包含数据字段enumType,那么函数getEnumSetFromStringList(List<String> list)如何获得泛型类型<E extends Enum<?>>的类型?E.class吗?如果不是,在编译过程中是出于泛型type-erasure的原因吗?发布于 2014-12-25 18:47:27
Enum<E extends Enum<E>>很难理解。
让我们考虑两个enums。
enum Colour { RED, GREEN, BLUE }
enum Shape { SQUARE, CIRCLE, TRIANGLE }
考虑一下compareTo()方法在Enum中。它用于根据声明的顺序比较同一Enum中的不同常量。如果Enum不是泛型类,则此方法的签名必须是int compareTo(Enum e)。但是这没有任何意义,因为这样您就可以将Colour与Shape进行比较。我们希望compareTo在Colour中的签名是int compareTo(Colour colour)。唯一的方法是如果Enum是一个具有类型参数E的泛型类,而Colour的类型参数是Colour!只要Colour的类型参数为Colour,而Shape的类型参数为Shape,则只能将Colours与Colours和Shapes与Shapes进行比较。
因此,在Enum的定义中,我们需要某种方式来表达,对于每个子类,类型参数不仅必须是enum,而且类型参数应该是子类本身。因此,E不应该仅仅扩展Enum,而是E应该扩展Enum<E>!
这就是Enum<E extends Enum<E>>的来历。
(您不应该编写Enum<E extends Enum<?>>)。
为enumType分配值的一种方法是将一个Class<E>传递给构造函数。像这样
class MyClass2<E extends Enum<E>> {
private final Class<E> enumType;
MyClass2(Class<E> enumType) {
this.enumType = enumType;
}
}如果不想这样做,在运行时获取Class<E>对象的另一种方法是使用Enum实例方法getDeclaringClass()。这要求您手头有一个E实例来调用该方法。在运行时获取所有枚举常量数组的一种方法是编写e.getDeclaringClass().getEnumConstants()。
您不能编写E.class,因为正如您正确地说的那样,泛型是使用类型擦除的过程实现的。在运行时,ArrayList<String>只是一个ArrayList,因此不可能访问类型参数。
发布于 2014-12-25 17:53:10
MyClass1和MyClass2有什么不同,这三种不同的E意味着什么?
MyClass1引入了一个名为E的泛型类型参数,它扩展了Enum<?>类。在这里,?意味着我们不知道(也不关心) Enum类的哪个泛型进行E扩展,因此使用了通配符。
同时,MyClass2还引入了一个名为E的泛型类型参数,它再次扩展了Enum类型。这一次,Enum类型由(相同的 E )泛型,这意味着该类型参数必须是Enum类的子类,并且还将支持在Enum中定义的使用完全相同类型E的所有方法。例如,这种方法是getDeclaringClass(),它将返回Class<E>而不是Class<Object>。
但是,不是所有Enum类型Enum的公共基类吗?
不是的。如果泛型参数不是Enum<E>的子类,它就没有意义。
如何在enumType中初始化数据字段MyClass?
您必须在构造函数中传递Class<E>,并将值复制到私有成员:
public MyClass(Class<E> enumType) {
this.enumType = enumType;
}如果MyClass不包含数据字段enumType,那么函数getEnumSetFromStringList(.)获取泛型类型的类型吗?
它不能得到它,因为类型-擦除。如果需要泛型类型的类,则必须维护一个包含Class<E>值的成员;
我可以这样得到Enum类型: E.class吗?如果没有,是因为在编译期间删除泛型类型的原因吗?
您不能这样做,因为E只是运行时特定内容的别名。
https://stackoverflow.com/questions/27649455
复制相似问题