首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对扩展exist Enum类型的泛型感到困惑

对扩展exist Enum类型的泛型感到困惑
EN

Stack Overflow用户
提问于 2014-12-25 17:43:04
回答 2查看 452关注 0票数 3

问题1:我对这些代码有点困惑:

代码语言:javascript
复制
public class MyClass1 <E extends Enum<?>> {
    // ...
}
public class MyClass2 <E extends Enum<E>> {
    // ... 
}

MyClass1MyClass2的区别是什么,这三种不同的E意味着什么?

问题2:来自Class Enum >

这是所有Java语言枚举类型的公共基类。

但是不是所有Enum类型的Enum<E>的公共基类吗?

问题3:现在我有一节课:

代码语言:javascript
复制
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;
    }
}
  1. 如何在enumType中用MyClass初始化数据字段
  2. 如果MyClass不包含数据字段enumType,那么函数getEnumSetFromStringList(List<String> list)如何获得泛型类型<E extends Enum<?>>的类型?
  3. 我可以这样得到Enum类型:E.class吗?如果不是,在编译过程中是出于泛型type-erasure的原因吗?
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 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)。但是这没有任何意义,因为这样您就可以将ColourShape进行比较。我们希望compareToColour中的签名是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>传递给构造函数。像这样

代码语言:javascript
复制
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,因此不可能访问类型参数。

票数 4
EN

Stack Overflow用户

发布于 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>,并将值复制到私有成员:

代码语言:javascript
复制
public MyClass(Class<E> enumType) {
    this.enumType = enumType;
}

如果MyClass不包含数据字段enumType,那么函数getEnumSetFromStringList(.)获取泛型类型的类型吗?

它不能得到它,因为类型-擦除。如果需要泛型类型的类,则必须维护一个包含Class<E>值的成员;

我可以这样得到Enum类型: E.class吗?如果没有,是因为在编译期间删除泛型类型的原因吗?

您不能这样做,因为E只是运行时特定内容的别名。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27649455

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档