Java公共枚举方法的目的

发布于 2024-12-02 05:59:59 字数 601 浏览 1 评论 0原文

所以我有我的枚举

public enum Sample {
   ValueA{
      @Override
   public String getValue(){ return "A"; }   
 },
 ValueB{
    @Override
   public String getValue(){ return "B"; }

   public void doSomething(){ }
 };
abstract public String getValue();
};

,还有一些其他代码尝试使用该枚举。

Sample.ValueB.doSomething();

这看起来应该是有效的,但会产生错误“方法 doSomething() 对于类型 Sample 来说是未定义的”。相反,

Sample value = Sample.ValueB;
value.doSomething();

它产生相同的错误并且看起来合理。

我认为对于为什么第一个不起作用有一个合理的答案,并且它与两个示例在幕后是等效的有关。我希望有人能指出我为什么会这样的文档。

So I have my enum

public enum Sample {
   ValueA{
      @Override
   public String getValue(){ return "A"; }   
 },
 ValueB{
    @Override
   public String getValue(){ return "B"; }

   public void doSomething(){ }
 };
abstract public String getValue();
};

and I have some other code trying to use the enum.

Sample.ValueB.doSomething();

Which seems like it should be valid, but produces the error "The method doSomething() is undefined for the type Sample". As opposed to

Sample value = Sample.ValueB;
value.doSomething();

which produces the same error and seems reasonable.

I assume there is a reasonable answer as to why the first one doesn't work and it relates to the two examples being equivalent under the hood. I was hoping someone could point me towards the documentation on why it is that way.

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

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

发布评论

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

评论(4

放手` 2024-12-09 05:59:59

“字段”ValueA 的类型是 Sample。这意味着您只能调用 Sample 提供的 ValueA 上的方法。来自 JLS §8.9.1 。枚举常量

仅当这些类体中声明的实例方法重写封闭枚举类型中的可访问方法时,才可以在封闭枚举类型外部调用它们。

更重要的是:从设计角度来看,enum 值应该是统一的:如果某个操作可以使用一个特定值进行,那么它应该可以使用所有值进行(尽管这可能会导致执行不同的代码)。

The type of the "field" ValueA is Sample. That means that you can only invoke methods on ValueA that Sample provides. From JLS §8.9.1. Enum Constants:

Instance methods declared in these class bodies may be invoked outside the enclosing enum type only if they override accessible methods in the enclosing enum type.

More importantly: From a design perspective enum values should be uniform: if some operation is possible with one specific value, then it should be possible with all values (although it might result in different code being executed).

2024-12-09 05:59:59

基本上,Sample.ValueB编译时类型仍然是 Sample,尽管该值的执行时类型将是 值B。因此,您的两个代码片段是等效的 - 客户端看不到仅存在于您的枚举值的一些中的“额外”方法。

您可以有效地将枚举视为声明如下字段:

public static final Sample ValueB = new Sample() {
    @Override
    public String getValue(){ return "B"; }

    public void doSomething(){ }
};

Basically the compile-time type of Sample.ValueB is still Sample, even though the execution-time type of the value will be ValueB. So your two snippets of code are equivalent - clients don't get to see the "extra" methods which are only present in some of your enum values.

You can effectively think of the enum as declaring a field like this:

public static final Sample ValueB = new Sample() {
    @Override
    public String getValue(){ return "B"; }

    public void doSomething(){ }
};
記憶穿過時間隧道 2024-12-09 05:59:59

当您编写时,

enum Sample
{
     Value{
        public void doSomething()
        {
              //do something
        }
    };
}

您并不是在创建 Sample 枚举的实例,而是创建 enum Sample 的匿名子类的实例。这就是为什么 doSomething() 方法未定义。

更新:这可以证明如下:

尝试

System.out.println(Sample.ValueB.getClass().getName());

打印 Sample$2

这意味着即使您在 Sample$2< 的实例中有方法 doSomething() /code> 您已命名为 ValueB,您通过 Sample 类型的超类引用来引用它,因此只有在类 Sample< 中定义的那些方法/code> 将在编译时可见。

不过,您可以在运行时通过反射调用 doSomething()

When you write

enum Sample
{
     Value{
        public void doSomething()
        {
              //do something
        }
    };
}

you are not creating an instance of the Sample enum, rather an instance of an anonymous sub-class of the enum Sample. Thet's why the method doSomething() is undefined.

Update: this can be proved as follows:

Try this

System.out.println(Sample.ValueB.getClass().getName());

prints Sample$2

Which means that even though you have the method doSomething() in the instance of Sample$2 which you have named ValueB, you are referring it through the super-class reference of type Sample and hence only those methods defined in the class Sample will be visible at compile time.

You can call that doSomething() at runtime via reflection though.

楠木可依 2024-12-09 05:59:59

public void doSomething(){ }private void doSomething(){ } 具有相同的效果。

doSomething() 在 ValueB 外部不可见,除非您将 doSomething() 添加到 Sample

每个 Sample 值都具有 Sample 类型,因此对于不同的值(从外部角度来看),它不能具有不同的方法集。

public void doSomething(){ } will have same effect as private void doSomething(){ }.

doSomething() is not visible outside ValueB unless you add doSomething() to the Sample.

Each Sample value has type Sample, so it cannot have different set of methods for different values (from outside perspective).

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