【问题标题】:Need to initialize a static final field in the subclasses需要在子类中初始化一个静态final字段
【发布时间】:2015-09-14 17:56:59
【问题描述】:

我问了一个问题,但是很脏,很多人不明白。所以,我需要声明一个最终的静态字段,它只会在子类中初始化。我举个例子:

public class Job {
    public static final String NAME;
}

public class Medic extends Job {

    static {
        NAME = "Medic";
    }
}

public class Gardener extends Job {

    static {
        NAME = "Gardener";
    }
}

类似的东西。我知道这段代码行不通,因为 Job 类中的 NAME 字段需要初始化。我想要做的是在每个子类(Medic、Gardener)中单独初始化该字段。

【问题讨论】:

  • static final 在这里没有多大意义。只需创建一个实例变量。
  • 为什么不创建创建抽象静态方法getName()
  • @Crozin 抽象静态方法?不可能:stackoverflow.com/a/370967/1743880
  • 我不想创建实例变量,因为我不想为了获得最终字段而创建新实例。我也不想创建方法,因为我想在不定义新方法的情况下找到解决方案。
  • @Ricjssubtil 你能举例说明你想如何访问最终字段吗?

标签: java static field final


【解决方案1】:

你需要这个

public enum Job {
    MEDIC(0),
    GARDENER(1);

    /**
     * get identifier value of this enum
     */
    private final byte value;

    private Job(byte value) {
        this.value = value;
    }

    /**
     * get identifier value of this enum
     * @return <i>int</i>
     */
    public int getValue() {
        return this.value;
    }

    /**
     * get enum which have value equals input string value
     * @param value <i>String</i> 
     * @return <i>Job</i>
     */
    public static Job getEnum(String value) {
        try {
            byte b = Byte.parseByte(value);
            for (Job c : Job.values()) {
                if (c.getValue() == b) {
                    return c;
                }
            }
            throw new Exception("Job does not exists!");
        } catch (NumberFormatException nfEx) {
            throw new Exception("Job does not exists!");
        }
    }

    /**
     * get name of this job
     */
    public String getName() {
        switch (this) {
        case MEDIC:
            return "Medic";
        case GARDENER:
            return "Gardener";
        default:
            throw new NotSupportedException();
        }
    }
}

【讨论】:

    【解决方案2】:

    为什么不在基类中声明抽象方法?

    public abstract class Job {
       public abstract String getJobName();
    }
    

    然后您可以在每个实现中返回单独的名称:

    public class Medic extends Job {
       @Override
       public String getJobName() {
          return "Medic";
       }
    }
    
    public class Gardener extends Job {
       @Override
       public String getJobName() {
          return "Gardener";
       }
    }
    

    拥有final static 字段没有多大意义。

    【讨论】:

      【解决方案3】:

      你不能这样做。 static 字段在每个声明它的类中只有一次实例。由于MedicGardener 共享相同的Job 超类,它们也共享相同的NAME 静态字段。因此你不能分配它两次。

      您甚至不能在子类中分配它一次,因为Job 类可能已经加载并初始化,但还没有加载子类。然而,在类初始化之后,所有static final 字段都需要初始化。

      【讨论】:

      • 谢谢,但现在我才想起枚举。我会使用它们。但是感谢您的帮助!
      • @Ricjssubtil,是的,枚举可能更适合您的问题
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-02
      • 1970-01-01
      • 2017-11-10
      相关资源
      最近更新 更多