【问题标题】:Java Generics: Enums and InterfacesJava 泛型:枚举和接口
【发布时间】:2013-07-04 23:16:35
【问题描述】:

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

我有许多扩展特定接口 (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();
    }
}

有代码:

public interface HasCode <T extends Enum<?>>{
    public int code();
    public T[] enumValues();
}

这是具有该魔术函数的类(迭代枚举的值)

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;
    }
}

我不喜欢这个:

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;
    }
}

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

【问题讨论】:

    标签: java generics interface


    【解决方案1】:

    您不必使用枚举的实例。你可以通过类并使用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());
        }
    }
    

    【讨论】:

    • 谢谢你,成功了。但是 value.name() 现在不能编译。更新主题以反映更改并添加相关问题。
    【解决方案2】:

    不确定为什么要对 HasCode 使用类型参数,只需在要使用的枚举上实现接口即可。我怀疑您试图将其用作将实现限制为枚举的一种方式,但这不是必需的。你不应该关心什么实现了一个接口。

    换一种方式试试

    createSelect(EnumSet.allOf(InvoiceStatus.class));
    
    public Hashtable createSelect(EnumSet<? extends HasCode> enums) {
        for (HasCode c : enums) {
            c.code();
        }
    }
    

    如果这对您很重要,您可以保证枚举将是 SetEnum 值。也更容易理解,并且您不需要直接使用枚举实例。

    【讨论】:

    • V[] values = anEnum.getEnumConstants(); -- "类型不匹配:无法从 Enum>[] 转换为 V[]
    • @Ibolit 尝试稍微不同的方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多