【问题标题】:If enums are implicitly static, why are they able to make use of the "this" keyword internally?如果枚举是隐式静态的,为什么它们能够在内部使用“this”关键字?
【发布时间】:2014-06-17 21:38:43
【问题描述】:

请原谅初学者级别的问题,但我对枚举的隐含静态状态感到困惑。

一方面,您不能在方法中声明它们,因为它们是隐式静态的,并且您可以像任何其他静态类一样从静态上下文中引用它们。但另一方面,在内部,它们将自己称为“这”就好像它们是一个实例一样。

代码示例:

public class EnumTest {

  enum Seasons{
      SUMMER,
      FALL,
      WINTER,
      SPRING;

      public String toString()
      {
          switch(this)
          {
              case SUMMER:
                  return "Hot Summer";
              case FALL:
                  return "Colorful Fall";
              case WINTER:
                  return "Crisp Winter";
              case SPRING:
                  return "Allergy Season";
              default
                  return "wth?";

          }
      }
  }
public static void main(String[] args)
{
   System.out.println(EnumTest.Seasons.SUMMER.toString());
}

}

注意在枚举定义中的 toString() 中,如何在“this”上有一个开关。

在静态方法 main 中,以典型的静态类方式访问 Enum。

我知道枚举是一种特殊类型的类,但我仍在尝试了解它们的一些非常规怪癖的原因。

当引用枚举常量时,是否存在某种工厂模式类型的自动构造?它究竟是在什么时候从静态类转变为实例的?

谢谢!

【问题讨论】:

  • 您也可以在静态类中使用this
  • public String toString() 是一个实例方法,因此this 在其中始终有效。
  • “它究竟在什么时候从静态类转变为实例?”。这个问题是没有意义的。没有什么可以从静态转变为实例。您可以拥有一个静态类的实例,但那里没有任何过渡。
  • case SPRING: return "Allergy Season"; 太真实了。

标签: java static enums


【解决方案1】:

枚举类中定义的常量是唯一隐含static 的东西。它接近(但不完全等同于):

public static final Seasons SUMMER = new Seasons();
public static final Seasons FALL = new Seasons();
public static final Seasons WINTER = new Seasons();
public static final Seasons SPRING = new Seasons();

这允许您编写诸如Seasons.SUMMER 之类的代码。

类体的其余部分就像一个普通的类体——public String toString() 不是隐含的static,因此它可以访问this

【讨论】:

  • 啊,好的。这也解释了为什么你不能像普通的静态嵌套类一样实例化类之外的嵌套枚举(例如 EnumTest.Seasons=new EnumTest().new Seasons(); 不会编译),但你可以引用 Enum来自类外部的常量,例如该类的静态数据成员,将其预先构造的值分配给类型为 OuterClass.EnumType 的变量(在本例中为 EnumTest.Seasons。)这有点像应用于嵌套类的 Multiton 模式,那么,不是吗?这很有帮助。枚举一直是我的弱点。谢谢。
【解决方案2】:

将枚举常量视为静态声明的对象,如下所示:

class A {

    public final static A FOO = new A ("FOO");
    public final static A BAR = new A ("BAR");

    private final String text;

    private A(String text) {
        this.text = text;
    }

    public String toString() {
        return this.text;
    }

}

虽然是静态声明的,但每个常量的对象都可以提供您可以调用的非静态方法。

【讨论】:

  • Java 中的常量是static final,而不仅仅是static
  • PS:为什么不直接编辑并添加一个明显的遗漏? ;-)
猜你喜欢
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-06
  • 2017-08-17
相关资源
最近更新 更多