Java Generics:枚举和接口

Ibo*_*lit 2 java generics interface

我已经阅读了一些关于此的主题,但仍然无法弄清楚我该怎么做我想做的事情:

我有许多扩展特定接口(HasCode)的枚举,它声明了一个函数code(),它返回此枚举的int代码.所有扩展枚举都有私有int变量和参数给它们的构造函数(等).

我希望有一个函数可以接受枚举类作为参数,并返回枚举值的名称和这些枚举值的int值的哈希表.

这是我的枚举的一个例子:

public enum InvoiceStatuses implements HasCode<InvoiceStatuses> {
    NONE(0), REQUESTED(10), RECEIVED(20), APPROVED(30), PAID(40), ERROR(-100);
    private int code;
    private InvoiceStatuses(int a) {
        code = a;
    }
    public int code() {
        return code;
    }
    public static InvoiceStatuses invoiceStatusByCode(int aCode) {
        switch (aCode) {
        case 0:
            return NONE;
        case 10:
            return REQUESTED;
        case 20:
            return RECEIVED;
        case 30:
            return APPROVED;
        case 40:
            return PAID;
        }
        return ERROR;
    }
    public int compare(InvoiceStatuses anotherLevel) {
        if (code > anotherLevel.code()) {
            return 1;
        } else if (code < anotherLevel.code()) {
            return -1;
        }
        return 0;
    }
    @Override
    public InvoiceStatuses[] enumValues() {
        return InvoiceStatuses.values();
    }
}
Run Code Online (Sandbox Code Playgroud)

HasCode:

public interface HasCode <T extends Enum<?>>{
    public int code();
    public T[] enumValues();
}
Run Code Online (Sandbox Code Playgroud)

这里是具有魔术功能的类(迭代枚举的值)

import java.util.Hashtable;
import java.util.LinkedList;
public class SelectFromEnum&lt;T extends Enum<?>> {
    public SelectFromEnum() {}
    public Hashtable<String, String> createSelect(HasCode<T> anEnum) throws Exception{
        if (! (anEnum instanceof Enum)) {
            throw new Exception ("I only accept enums...");
        }
        T[] values = anEnum.enumValues();
        for (T value : values) {
            System.out.println(value.name() + " __ " + ((HasCode)value).code());
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我不喜欢这个:

1)我必须将一个具体的枚举成员作为参数传递给createSelect函数,我想传递(enum).class;

2)我想createSelect指定它的参数是一个扩展给定接口枚举,但我不知道如何做到这一点.

更新:

根据Ingo Kegel的评论我修改了SelectFromEnum以下方式(见下文),现在value.name()不编译......

import java.util.Hashtable;
import java.util.LinkedList;

public class SelectFromEnum<C extends HasCode> {
    public SelectFromEnum() {
    }
    public Hashtable&lt;String, String> createSelect(Class<C> anEnum) throws Exception {
        if (!anEnum.isEnum()) { 
            throw new Exception("I only accept enums...");
        }
        C[] values = anEnum.getEnumConstants();
        for (C value : values) {
            System.out.println(value.name() + " __ " + value.code());
        }
        return null;
    }
}
Run Code Online (Sandbox Code Playgroud)

我可以添加name()HasCode接口,但有没有办法说服编译器value是一个枚举成员?

Ing*_*gel 8

您不必使用枚举的实例.您可以传递该类并使用Class#isEnumClass#getEnumConstants().

编辑

你可以转换为返回的对象由Class#getEnumConstants()Enum您的代码应该是这样的:

public LinkedList createSelectFrom(Class anEnum) throws Exception {
    if (!anEnum.isEnum()) {
        throw new Exception("I only accept enums...");
    }
    Object[] values = anEnum.getEnumConstants();
    for (Object value : values) {
        System.out.println(((Enum)value).name() + " __ " + ((HasCode) value).code());
    }
}
Run Code Online (Sandbox Code Playgroud)