代码之家  ›  专栏  ›  技术社区  ›  Dexygen

Java方法可以返回类型枚举吗?

  •  7
  • Dexygen  · 技术社区  · 15 年前

    我可能错了,但我猜 Why can't enums be declared locally in a method? 由于Java中的枚举不能在本地声明,因此返回枚举类型的方法有问题吗?我可以声明一个方法应该返回一个枚举(见下文),但是如何实现这样一个方法来返回除null以外的任何东西,或者对在该方法之外声明的枚举的引用?我的第一个倾向是研究使用仿制药来解决这个问题,但是我想避免任何死路一条,如果SO社区能够帮助我避免死路一条。

    private Enum resources() {
        return null;
    }
    
    7 回复  |  直到 9 年前
        1
  •  8
  •   David Moles paddy-p    9 年前

    我认为你是对的,它只能返回 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(),但您得到了这个想法。)

        2
  •  3
  •   Bill K    15 年前

    Java做Enums的整个步骤是,它们是类型化的——所以你不会返回枚举(这是双加不好的),而不是返回你定义的实际类型(比如“TAY”),它就像一个类。诉讼有4个“列举”的实例。

    如果你期待着一件“西装”,那么返回7级的“军衔”会有什么好处呢?它会破坏一切!

    另外,如果传递了“枚举”或一些泛型值,则无法对其调用方法。关于typesafe枚举最酷的一点是,您只需获得一个“suit”并调用“suit.get color()”,就可以完全期望获得该套装的颜色。您还可以拥有Rankshigherthan(西服),可以满足:

    assertTrue(SPADES.ranksHigherThan(HEARTS));
    

    或者更重要的是:

    suit1.ranksHigherThan(suit2);
    

    (假设他们都被传了进来,而你不知道他们是什么)

    类型安全是非常惊人的(即使一开始感觉有点不舒服),拥抱它。

        3
  •  3
  •   Dean Povey    15 年前

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

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

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

        4
  •  2
  •   davetron5000    15 年前

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

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

        5
  •  1
  •   Robert Munteanu    15 年前

    是的,这绝对是可能的。

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

    如果你的问题是关于 宣告 Enums,您可以声明:

    • 在自己的Java文件中,类似于顶层 class ;
    • 在属于另一个类的Java文件中,类似于静态内部 ;
        6
  •  1
  •   aperkins    15 年前

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

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

    不完全确定在那里你会得到什么,尽管如果你谈论的是不同的枚举集和它们的元素,这是有益的。

    如果您谈论的是枚举类(即Percursor-to-Iterator),据我所知,它还没有被泛型化,所以我不确定泛型在这里会有什么帮助。

        7
  •  1
  •   starblue    15 年前

    可以通过枚举的名称引用它的值,例如suit.spades。

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