Java 方法可以返回 Enum 类型吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1429538/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 11:58:00  来源:igfitidea点击:

Can Java methods return type Enum?

javagenericsenumsmethod-signature

提问by Dexygen

I could be wrong but I'm guessing from Why can't enums be declared locally in a method?that, since an enum in Java cannot be declared locally, that therefore it is problematic for a method to return type Enum? I can declare that a method should return an Enum (see below) but how would one then go about implementing such a method to return anything other than null, or a reference to an Enum declared outside the method? My first inclination would be to investigate using Generics for this but I'd like to avoid any deadends if the SO community can help me avoid them.

我可能是错的,但我从为什么不能在方法中本地声明枚举?那,由于Java中的枚举不能在本地声明,因此返回类型枚举的方法是有问题的?我可以声明一个方法应该返回一个 Enum(见下文),但是如何实现这样一个方法来返回除 null 以外的任何内容,或者对在方法之外声明的 Enum 的引用?我的第一个倾向是为此调查使用泛型,但如果 SO 社区可以帮助我避免它们,我想避免任何死胡同。

private Enum resources() {
    return null;
}

采纳答案by David Moles

I think you're correct, it's only going to be able to either return nullor an Enumdeclared somewhere else. But you don't necessarily have to specify that "something else" at compile time.

我认为你是对的,它只能返回null或在Enum其他地方声明。但是您不必在编译时指定“其他东西”。

  class EnumEnumerator<T extends Enum<T>> implements Iterable<T> {
    private final Class<T> enumClass;

    public EnumEnumerator(Class<T> enumClass) {
      this.enumClass = enumClass;
    }

    public Iterator<T> iterator() {
      T[] values = enumClass.getEnumConstants();
      return Arrays.asList(values).iterator();
    }
  }

Later, you invoke it by specializing the generic constructor and passing in the enum class you're interested in:

稍后,您通过专门化泛型构造函数并传入您感兴趣的枚举类来调用它:

class EnumEnumeratorDemo {
    enum Foo {
        BAR, BAZ, QUX;
        @Override public String toString() {
            return name().toLowerCase();
        }
    }

    public static void main(String[] args) {
        for (Foo f : new EnumEnumerator<Foo>(Foo.class)) {
            System.out.println(f);
        }
    }
}

(Obviously this is a contrived example and in real life you should just call Foo.values(), but you get the idea.)

(显然这是一个人为的例子,在现实生活中你应该只调用 Foo.values(),但你明白了。)

回答by davetron5000

What are you trying to accomplish? This is a way to return an Enum:

你想达到什么目的?这是返回一个的方法Enum

public class Test
{
    public static void main(String args[])
    {
        System.out.println(doit());
    }

    public enum Foo {
        BAR,
        BAZ;
    }
    public static Enum doit() {
        return Enum.valueOf(Foo.class,"BAR");
    }
}

But, I'm guessing this is not what you are going for?

但是,我猜这不是你想要的吗?

回答by Robert Munteanu

Yes, it definitely is possible.

是的,这绝对是可能的。

private Enum getRetentionPolicy() {
    return java.lang.annotation.RetentionPolicy.SOURCE;
}

If your question is about declaringEnums, you may declare them:

如果您的问题是关于声明枚举,您可以声明它们:

  • in their own java file, similar to a top-level class;
  • within a java file belonging to another class, similar to a static inner class;
  • 在自己的java文件中,类似于一个顶级的class
  • 在属于另一个类的 java 文件中,类似于静态内部class

回答by aperkins

Not totally sure what your goal is, but if you wanted to return a generified method (i.e. one that would be overridden) you might have something like the following:

不完全确定你的目标是什么,但如果你想返回一个泛型方法(即一个将被覆盖的方法),你可能有如下内容:

public class MyEnumClass<T extends Enum<T>> {
    public T resources() {
        //do stuff here
    }
}

Not entirely sure what you would gain there, although it can be beneficial if you are talking about different sets of Enums and their elements.

不完全确定您会在那里获得什么,尽管如果您谈论的是不同的枚举集及其元素,这可能会有所帮助。

If you are talking about the Enum class (i.e. the percursor to Iterator) as far as I know it has not been generified, so I am not sure generics would help much here.

如果你在谈论 Enum 类(即迭代器的 percursor),据我所知它还没有被泛化,所以我不确定泛型在这里会有多大帮助。

回答by starblue

You can refer to a value of an enum by its name, e.g. Suit.SPADES.

您可以通过名称引用枚举的值,例如 Suit.SPADES。

You can iterate over all values by using the values() method and pick one of the values.

您可以使用 values() 方法迭代所有值并选择其中一个值。

回答by Dean Povey

All enums implement the interface Enum, so you can certainly write a method that returns an enum this way. But this method will return a single enum value. There is no way to return a generic value which encompasses the whole enum (apart from returning the class and doing reflection). You can however return all the enum values which is more or less what you want I think.

所有枚举都实现了 Enum 接口,因此您当然可以编写一个以这种方式返回枚举的方法。但是此方法将返回单个枚举值。没有办法返回包含整个枚举的泛型值(除了返回类并进行反射)。但是,您可以返回我认为或多或少想要的所有枚举值。

enum Resources { ONE, TWO, THREE }
private Enum<?>[] resources() {
    return Resources.values();
}

One benefit of this approach is you can return more or less values for example:

这种方法的一个好处是您可以返回更多或更少的值,例如:

enum Resources { ONE, TWO, THREE }
enum MoreResources { UN, DEUX, TROIS }
private Enum<?>[] resources() {
    List<Enum<?>> resources = new ArrayList<Enum<?>>();
    resources.addAll(Arrays.asList(Resources.values());
    resources.addAll(Arrays.asList(MoreResources.values());
    return resources.toList(new Enum<?>[] {});
}

An even better approach that is more typesafe is to have the enums of interest implement a common interface e.g.

一种更类型安全的更好方法是让感兴趣的枚举实现一个通用接口,例如

public interface Resources {}
enum SomeResources implements Resources { ONE, TWO, THREE }
enum MoreResources implements Resources { UN, DEUX, TROIS }
private Resources[] resources() {
    List<Resources> resources = new ArrayList<Resources>();
    resources.addAll(Arrays.asList(Resources.values());
    resources.addAll(Arrays.asList(MoreResources.values());
    return resources.toList(new Resources[] {});
}

You can add additional methods to the interface to provide more functionality.

您可以向接口添加其他方法以提供更多功能。

回答by Bill K

The entire point of the way Java does Enums is that they are typesafe--so you wouldn't return an Enum (that would be double-plus ungood) instead you return the actual type you define (like "Suit") which acts just like a class. Suit has 4 "Enumerated" instances.

Java 做 Enums 的整个方式是它们是类型安全的——所以你不会返回一个 Enum(这将是双加不好),而是返回你定义的实际类型(比如“Suit”),它只是起作用就像一个班级。Suit 有 4 个“枚举”实例。

If you were expecting a "Suit", what good would it be to return a "Rank" of 7? It would break everything!

如果您期待“套装”,返回 7 的“等级”有什么好处?它会打破一切!

Also if you passed an "Enum" or some generic value, you couldn't call methods on it. The coolest thing about TypeSafe Enums is that you can just get a "Suit" and call "Suit.getColor()" and fully expect to get the color of that suit. You could also have a ranksHigherThan(Suit s) which might fulfill:

此外,如果您传递了“Enum”或一些通用值,则无法对其调用方法。TypeSafe Enums 最酷的事情是你可以得到一个“Suit”并调用“Suit.getColor()”并完全期望获得该套装的颜色。你也可以有一个 rankHigherThan(Suit s) 可能满足:

assertTrue(SPADES.ranksHigherThan(HEARTS));

Or, more importantly:

或者,更重要的是:

suit1.ranksHigherThan(suit2);

(assuming they were both passed in and you don't know what they are)

(假设它们都被传入并且您不知道它们是什么)

Type safety is really amazing (even though it feels a little uncomfortable at first), embrace it.

类型安全真的很棒(尽管一开始感觉有点不舒服),拥抱它。