为什么两个枚举常量可以在同一行中使用?

问题描述 投票:4回答:1

我创建了一个Enum类:

public enum Currency {

    PENNY(1), NICKLE(5), DIME(10), QUARTER(25);

    private int value;

    private Currency(int value) {
        this.value = value;
    }

};

我试图在main()方法中使用它:

System.out.println(Currency.NICKLE.DIME.PENNY.QUARTER);
System.out.println(Currency.PENNY.QUARTER);

这没有产生错误。它打印最后的常量。

有人可以解释一下吗?

java enums
1个回答
2
投票

我将尝试在上述评论中添加更多内容。

枚举值有些特殊。来自Java枚举的Wikipedia条目:

Java中的枚举类型实际上是一个特殊的编译器生成的类而不是算术类型,枚举值表现为该类的全局预生成实例。枚举类型可以包含实例方法和构造函数(可以为每个枚举值单独指定其参数)。

因此,虽然它们仅在编译时生成一次,但它们是给定枚举类型的特殊实例。因此,它可以访问该类的其他成员。请注意,这也意味着您无法自己实例化枚举类型(即使用new)。

从枚举类的一个实例,您可以访问相同枚举类的另一个实例?我在普通的Java类中没有看到过。

这在普通班级也是可能的,虽然不赞成,因为它没有提供真正的好处,甚至可能导致问题和错误(通过NullPointerExceptions)。

考虑以下两个类:

public class SomeClass
{
  public final static int MODE = 1;
  private String message;

  public SomeClass(String message)
  {
    this.message = message;
  }
}

public class Test
{
  public static void main(String[] args)
  {
    SomeClass myObject = new SomeClass("bla");
    System.out.println(myObject.MODE);
    System.out.println(OtherClass.MODE);
  }
}

这只会打印出来:

1
1

但是,假设您正在执行某些任务,您在其中迭代SomeClass对象列表,其中某些条目可能是null(可能是因为它们在某些时候被从集合中删除,或者因为null条目在插入时被允许用于任何原因)。

在这种情况下,如果您通过实例访问static成员,您将获得NPE,而通过类本身访问它将按预期工作。

请注意,问题中描述的行为特定于enum类型本身(即Currency.NICKLE.DIME...)。有一种方法可以模仿这种行为,如下所示:

public class SomeClass
{
  public static SomeClass REF; // not final anymore since 'this' must be the first line in a constructor call
  public String message; // note this is public now

  public SomeClass(String message)
  {
    this.message = message;
  }

  public void setRef() {
    REF = this;
  }
}

public class Test
{
  public static void main(String[] args)
  {
    SomeClass myObject = new SomeClass("bla!");
    System.out.println(myObject.REF);
    System.out.println(SomeClass.REF);
    myObject.setRef();
    System.out.println(SomeClass.REF);
    System.out.println(SomeClass.REF.message);
  }
}

这将打印出来:

null
null
SomeClass@...  // Object.toString() call
bla!

但是使用这种糟糕的技术和许多缺点绝对没有任何好处。

© www.soinside.com 2019 - 2024. All rights reserved.