簡體   English   中英

Java Enum靜態最終實例變量

[英]Java Enum Static Final Instance Variables

好哇!

這段代碼工作了一段時間,然后我決定添加一個默認顏色,它停止工作。 我收到以下錯誤:

1 error found:
File: Status.java  [line: 20]
Error: Status.java:20: illegal reference to static field from initializer

在編譯時使用以下代碼。

import java.awt.Color;

enum Status
{
  OFF ("Off"),
  TRAINING ("Training", new Color(255, 191, 128)),
  BEGINNER ("Beginner", new Color(128, 255, 138)),
  INTERMEDIATE ("Intermediate", new Color(128, 212, 255)),
  ADVANCED ("Advanced", new Color(255, 128, 128));

  public final String name;
  public final Color color;

  public static final Color defaultColor = Color.WHITE;

  Status(String name)
  {
    this(name, defaultColor);
  }
  Status(String name, Color color)
  {
    this.name = name;
    this.color = color;
  }
}

據我所知,這應該可以工作,但無論出於什么原因,Java決定拋出一個錯誤。 有什么想法嗎?

defaultColor只會在調用構造函數初始化 - 因此在此之前它將具有默認值(null)。 一種選擇是將默認顏色放在嵌套類型中:

import java.awt.Color;

enum Status
{
  OFF ("Off"),
  TRAINING ("Training", new Color(255, 191, 128)),
  BEGINNER ("Beginner", new Color(128, 255, 138)),
  INTERMEDIATE ("Intermediate", new Color(128, 212, 255)),
  ADVANCED ("Advanced", new Color(255, 128, 128));

  public final String name;
  public final Color color;

  Status(String name)
  {
    this(name, Defaults.COLOR);
  }
  Status(String name, Color color)
  {
    this.name = name;
    this.color = color;
  }

  private static class Defaults
  {
     private static Color COLOR = Color.WHITE;
  }
}

當然,如果您只在代碼中引用一次默認顏色,那么您也可以在構造函數調用中對其進行硬編碼:

Status(String name)
{
  this(name, Color.WHITE);
}

必須首先初始化枚舉常量。 要初始化它們,必須調用構造函數。 第一個構造函數引用一個靜態字段,該字段在調用時可能無法初始化。

Java允許這樣做

class Status
{
    public static final Status OFF = new Status("Off");

    public static final Color defaultColor = Color.WHITE;

    Status(String name)
    {
      this(name, defaultColor);
    }
}

當然它在運行時會有問題,但Java並不關心。 程序員的工作是安排init序列,編譯器檢查所​​有破壞的init依賴項並不容易。 無論如何,問題很容易解決:

class Status
{
    // now it works, this field is initialized first
    public static final Color defaultColor = Color.WHITE;

    public static final Status OFF = new Status("Off");

但是對於enum ,這種解決方法不適用,因為enum類型中的靜態字段在enum之前無法移動(可能出於純語法原因)。 為了避免混淆,Java為enum添加了一個額外的限制 - 靜態字段不能從構造函數中引用。

這種限制是半生的。 從構造函數中檢查靜態字段的所有可能用法並不容易(如果不是不可能)。 以下代碼將編譯,擊敗限制:

enum Status
{
    OFF("Off");

    public static final Color defaultColor = Color.WHITE;
    static Color defaultColor(){ return defaultColor; }

    Status(String name)
    {
      this(name, defaultColor());
    }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM