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

时间:2009-09-15 20:48:55

标签: java generics enums method-signature

我可能错了,但我猜是来自Why can't enums be declared locally in a method?  因为Java中的枚举不能在本地声明,因此返回类型Enum的方法有问题吗?我可以声明一个方法应该返回一个枚举(见下文),但是如何实现这样的方法来返回除null之外的任何东西,或者对在方法外声明的枚举的引用呢?我的第一个倾向是调查使用泛型,但如果SO社区可以帮助我避免它们,我想避免任何延迟。

private Enum resources() {
    return null;
}

7 个答案:

答案 0 :(得分:8)

我认为你是对的,它只能返回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();
    }
  }

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

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

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

答案 1 :(得分:3)

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

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

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

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<?>[] {});
}

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

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[] {});
}

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

答案 2 :(得分:3)

Java做Enums的方式的全部意义在于它们是类型安全的 - 所以你不会返回一个枚举(这将是双倍加上ungood),而是返回你定义的实际类型(如“Suit”)这就像一个班级。 Suit有4个“Enumerated”实例。

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

此外,如果您传递了“枚举”或某些通用值,则无法在其上调用方法。关于TypeSafe Enums最酷的事情是你可以得到一个“套装”并调用“Suit.getColor()”并完全期望获得该套装的颜色。你也可以拥有一个可能满足的职业高手(西装):

assertTrue(SPADES.ranksHigherThan(HEARTS));

或者,更重要的是:

suit1.ranksHigherThan(suit2);

(假设他们都被传入,你不知道他们是什么)

类型安全真的很棒(尽管起初感觉​​有些不舒服),接受它。

答案 3 :(得分:2)

你想要完成什么?这是一种返回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");
    }
}

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

答案 4 :(得分:1)

是的,这绝对是可能的。

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

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

  • 在他们自己的java文件中,类似于顶级class;
  • 属于另一个类的java文件,类似于静态内部class;

答案 5 :(得分:1)

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

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

不完全确定你会在那里获得什么,虽然如果你谈论不同的枚举及其元素,这可能是有益的。

如果你正在谈论Enum类(即Iterator的前兆),据我所知它没有被广泛化,所以我不确定泛型在这里会有多大帮助。

答案 6 :(得分:1)

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

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