8

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

private Enum resources() {
    return null;
}
4

7 回答 7

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(),但你明白了。)

于 2009-09-17T10:46:24.017 回答
4

Java 做 Enums 的方式的全部要点是它们是类型安全的——所以你不会返回一个 Enum(那将是双加不好),而是返回你定义的实际类型(比如“Suit”),它的作用只是像一堂课。西装有 4 个“枚举”实例。

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

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

assertTrue(SPADES.ranksHigherThan(HEARTS));

或者,更重要的是:

suit1.ranksHigherThan(suit2);

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

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

于 2009-09-15T21:35:43.677 回答
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[] {});
}

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

于 2009-09-15T21:01:15.107 回答
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");
    }
}

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

于 2009-09-15T20:56:51.077 回答
1

是的,这绝对是可能的。

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

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

  • 在他们自己的java文件中,类似于一个顶级的class
  • 在属于另一个类的 java 文件中,类似于静态内部class
于 2009-09-15T20:58:17.453 回答
1

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

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

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

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

于 2009-09-15T20:58:36.377 回答
1

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

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

于 2009-09-15T20:58:59.367 回答