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

发布于 2024-08-05 01:00:10 字数 348 浏览 3 评论 0原文

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

private Enum resources() {
    return null;
}

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.

private Enum resources() {
    return null;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

一梦等七年七年为一梦 2024-08-12 01:00:10

我认为你是对的,它只能返回 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(),但您明白了。)

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

  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.)

榆西 2024-08-12 01:00:10

Java 处理枚举的方式的全部要点在于它们是类型安全的——所以你不会返回一个枚举(这将是双加不好的),而是返回你定义的实际类型(如“Suit”),它的作用只是就像一个班级。套装有 4 个“枚举”实例。

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

此外,如果您传递了“Enum”或某些通用值,则无法对其调用方法。 TypeSafe Enums 最酷的一点是,您只需获取“西装”并调用“Suit.getColor()”,并完全期望获得该西装的颜色。您还可以有一个ranksHigherThan(Suit s),它可能满足:

assertTrue(SPADES.ranksHigherThan(HEARTS));

或者,更重要的是:(

suit1.ranksHigherThan(suit2);

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

类型安全性确实令人惊叹(尽管感觉有点不舒服)首先),拥抱它。

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.

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

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:

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.

ぃ双果 2024-08-12 01:00:10

所有枚举都实现了 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[] {});
}

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

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 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.

梦回旧景 2024-08-12 01:00:10

你想实现什么目标?这是一种返回 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");
    }
}

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

What are you trying to accomplish? This is a way to return an 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?

〆一缕阳光ご 2024-08-12 01:00:10

是的,这绝对是可能的。

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

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

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

Yes, it definitely is possible.

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

If your question is about declaring Enums, 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;
長街聽風 2024-08-12 01:00:10

不完全确定您的目标是什么,但是如果您想返回一个泛型方法(即会被覆盖的方法),您可能会遇到如下情况:

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

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

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

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.

清风夜微凉 2024-08-12 01:00:10

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

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

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文