简体   繁体   English

l如何从泛型类型的实例调用values() <E extends Enum<E> &gt;?

[英]How l can call values() from instance of generic type <E extends Enum<E>>?

public static <E extends Enum<E>> void example(E e){
    e. //what should I put here to get result of values()?
}

I am trying to call the method values() that returns the values of an enum using this method with generic arguments. 我试图调用使用此方法和泛型参数返回enum值的方法values()

How can I do that? 我怎样才能做到这一点?

Enum doesn't have values() method. Enum没有values()方法。 It is added by compiler later to each of your Enum subclasses (when we are creating our own enum YourEnum{...} type). 稍后由编译器将其添加到您的每个Enum子类中(当我们创建自己的enum YourEnum{...}类型时)。 So we can't invoke values() from Enum type. 因此,我们无法从Enum类型调用values()

Possible solution is 可能的解决方案是

E[] values = e.getDeclaringClass().getEnumConstants();

To be safe we should use getDeclaringClass() instead of getClass() , because enum values can be implemented as anonymous classes like in case of TimeUnit 为了安全起见,我们应该使用getDeclaringClass()而不是getClass() ,因为枚举值可以像TimeUnit一样实现为匿名类

public enum TimeUnit {
    /**
     * Time unit representing one thousandth of a microsecond
     */
    NANOSECONDS {
        public long toNanos(long d)   { return d; }
        public long toMicros(long d)  { return d/(C1/C0); }
        public long toMillis(long d)  { return d/(C2/C0); }
        public long toSeconds(long d) { return d/(C3/C0); }
        public long toMinutes(long d) { return d/(C4/C0); }
        public long toHours(long d)   { return d/(C5/C0); }
        public long toDays(long d)    { return d/(C6/C0); }
        public long convert(long d, TimeUnit u) { return u.toNanos(d); }
        int excessNanos(long d, long m) { return (int)(d - (m*C2)); }
    },

In this case 在这种情况下

  • TimeUnit.NANOSECONDS.getClass() returns java.util.concurrent.TimeUnit$3 (but this anonymous class doesn't contain any enum values) TimeUnit.NANOSECONDS.getClass()返回java.util.concurrent.TimeUnit$3 (但此匿名类不包含任何枚举值)
  • TimeUnit.NANOSECONDS.getDeclaringClass() returns java.util.concurrent.TimeUnit (with contains all of enum values). TimeUnit.NANOSECONDS.getDeclaringClass()返回java.util.concurrent.TimeUnit (包含所有枚举值)。

It will also save us some trouble with casting since 这也将为我们节省铸造方面的麻烦,因为

  • getDeclaringClass returns Class<E> getDeclaringClass返回Class<E>
  • getClass() returns Class<? extends E> getClass()返回Class<? extends E> Class<? extends E>

So result type of 所以结果类型

  • getDeclaringClass().getEnumConstants() is E[] getDeclaringClass().getEnumConstants()E[]
  • while getClass().getEnumConstants() is ? extends Enum[] getClass().getEnumConstants()? extends Enum[] ? extends Enum[] . ? extends Enum[]

This allows us to create loop like without need to involve casting: 这使我们无需创建强制转换就可以创建循环:

for (E value : e.getDeclaringClass().getEnumConstants()){
    //handle value
}

As an extra, you can also get all values from Class<E> (where <E extends Enum<E>> ) by using EnumSet.allOf(enumClass) like in case of code from this question: 另外,您也可以使用EnumSet.allOf(enumClass)Class<E> (其中<E extends Enum<E>> )中获取所有值,就像该问题的代码一样:

EnumSet<E> allOf = EnumSet.allOf(e.getDeclaringClass());

Well, there is a method in the clas Class<T> called getEnumConstants() which does just that. 好吧,clas Class<T>名为getEnumConstants()可以做到这一点。 So i had this method that printed out the enum constants given any enum value here: 所以我有这种方法在这里给出任何枚举值的情况下打印出枚举常量:

public <E extends Enum<E>> void printEnums(E e){
    for(E value : e.getDeclaringClass().getEnumConstants()){
        System.out.println("Value: "+value);
    }
}

To call it i would use something like 可以这样称呼我
printEnums(Enum.SOME_VALUE);

although I think the following method is better because it takes as parameter the class of the enum directly: 尽管我认为以下方法更好,因为它直接将枚举的类作为参数:

public static <E extends Enum<E>> void printEnums(Class<E> e){
    for(E value : e.getEnumConstants()){
        System.out.println("Value: "+value);
    }
}

You can call this method like so: printEnums(EnumClass.class); 您可以像这样调用此方法: printEnums(EnumClass.class);

I know you are not asking how to print the enum values, but these methods above are good to give you a headstart on how to access the constants given the type or the class. 我知道您不是在问如何打印枚举值,但是上面的这些方法可以让您在如何访问给定类型或类的常量方面有所作为。

EDIT 1: Changed the code. 编辑1:更改代码。 Thanks @JBNizet 谢谢@JBNizet

EDIT 2: Changed the code again according to @Tunaki's comment. 编辑2:根据@Tunaki的评论再次更改了代码。 Note: this was initially adressed on Pshemo's answer 注意:这最初是针对Pshemo的回答

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 为什么不从枚举扩展<e extends enum<e> ></e> - Why not extending from Enum<E extends Enum<E>> 怎么做 <T extends E> 泛型类型参数包容性? - How to make <T extends E> generic type argument inclusive? 为什么“类型绑定不匹配:类型? 扩展T不是有界参数的有效替代品 <E extends Enum<E> &gt;枚举类型 <E> “? - Why ”Type Bound mismatch: The type ? extends T is not a valid substitute for the bounded parameter <E extends Enum<E>> of the type Enum<E>“? 如何使用扩展类 <E extends Comparable<E> &gt; - How to extend Generic abstract Class with <E extends Comparable<E>> 可实例化的Java通用 <E extends Comparable<E> &gt; - An instantiable Java generic for <E extends Comparable<E>> 数组列表 <Enum> 返回“对泛型类型Enum的引用 <e> 应该参数化 - ArrayList<Enum> returns "References to generic type Enum<e> should be parameterized Collection类型不是通用的;它不能用参数<?参数化延伸E> - The type Collection is not generic; it cannot be parameterized with arguments <? extends E> 如何创建E类型的Java列表扩展Comparable <? super E> - How to create Java List of Type E extends Comparable<? super E> C#相当于Java类 <E> 和E扩展枚举 <E> - C# equivalent of java Class<E> and E extends Enum<E> 最简单的方法来转换类 <T> 到一个班级 <E extends Enum<E> &gt;不丢失类型信息 - Simplest way to cast a Class<T> to a Class<E extends Enum<E>> without losing type information
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM