java - 对扩展现有枚举类型的泛型感到困惑

标签 java generics interface enums type-erasure

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

public class MyClass1 <E extends Enum<?>> {
    // ...
}
public class MyClass2 <E extends Enum<E>> {
    // ... 
}

MyClass1 之间有什么不同?和 MyClass2 , 这三个不同的是什么 E什么意思?

问题 2:来自 Class Enum <E extends Enum<E>>

This is the common base class of all Java language enumeration types.

但不是所有枚举类型的公共(public)基类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;
    }
}
  1. 如何初始化数据字段 enumTypeMyClass ?

  2. 如果 MyClass不包含数据字段 enumType ,函数怎么可能getEnumSetFromStringList(List<String> list)获取通用类型的类型 <E extends Enum<?>> ?

  3. 我可以这样获取枚举类型吗:E.class ?如果不是,是不是编译时泛型的type-erasure原因?

最佳答案

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 .我们想要 compareTo 的签名在 Colour成为int compareTo(Colour colour) .唯一的方法是如果 Enum是具有类型参数 E 的泛型类和 Colour 的类型参数是Colour !只要Colour的类型参数是ColourShape 的类型参数是Shape那我们只能比较Colour s 至 Colour s 和 Shape s 至 Shape

所以在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 , 因此无法访问类型参数。

关于java - 对扩展现有枚举类型的泛型感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27649455/

相关文章:

java - 有人可以向我解释为什么 L(长)必须在那里吗?

java - 如何从 Java Swing/GUI 调用 JavaFXApplication?这可能吗?

c# - 创建对象泛型类

java - 如何使用泛型返回泛型类的类类型?

java - Comparable 是原始类型。对泛型类型 Comparable<T> 的引用应该参数化

java - 如何在没有按钮或文本区域的情况下使用 KeyListener?

java - BIRT 报告 - 遍历报告元素

c++ - C++ 中的抽象类(接口(interface))数组

java - 在 C++ 中重叠类似 java 的接口(interface)

c# - 在这种情况下如何返回 List<MyInterface>