【问题标题】:Usage of final and static for a constant that is unknown at class load-up对类加载时未知的常量使用 final 和 static
【发布时间】:2015-12-09 22:55:37
【问题描述】:

在课堂上,我声明了一个从作业开始就不会改变的字段。该字段(准确地说是常量)也由该类的所有实例共享。

出于以上两个原因,我使用的是

最终

静态

声明常量时的关键字。

但是,由于我同时使用 final 和 static,我需要在声明时分配一个值,因为在加载类时常量被分配了它的值。不幸的是,在这种情况下,无法做到这一点,因为程序从一开始就不知道该值,而只有在实例化类时才知道(因为它的值是由程序计算出来的)。因此,必须根据传递给它的参数在类的构造函数中为其赋值。

如前所述,这在 java 中是非法的。

我不知道如何解决这个问题。一切都表明我应该同时使用 static 和 final,因为该字段由该类的所有实例共享,并且从为其分配值的那一刻起就不会改变。

此外,根据 Android 文档,使用 final 关键字具有以下优点:

访问 [a final field] 将使用相对便宜的“字符串 常量”指令而不是字段查找。

此外,使用 static 关键字的优点是所有实例只使用一个字段,而不是每个实例使用一个字段。

因此,出于性能原因,我能够同时使用这两个关键字非常重要。

总结:我需要同时使用 final 和 static 但是,因为在类加载时常量的值是未知的,所以我不能这样做。是否有解决方法,以便我仍然可以使用 final 和 static 作为我的常量?

【问题讨论】:

标签: java static final


【解决方案1】:

不。如果一个静态字段是 final 的,那么它必须被内联初始化:

public static final String CONSTANT = "blah";

或在静态初始化器中:

public static final String CONSTANT;
static {
    CONSTANT = "blah";
}

关于如何解决它,这听起来像是一个奇怪的设计,您想在构造函数中初始化值,但它被所有实例使用。构造第二个实例时会发生什么?该参数的值是否被忽略?

【讨论】:

    【解决方案2】:

    我建议你用静态方法替换你的静态常量,因为你实际上需要控制某个值是否已经被初始化:

    public final class MyConstants
    {
        private MyConstants(){}
    
        private static <type> constant1;
    
        public static void setConstant1(<type> value)
        {
            if (constant1==null)
            {
                throw new IllegalStateException("Constant1 clready initialized");
            }
            else
            {
                constant1=value;
            }
        }
    
        public static <type> getConstant1()
        {
            if (constant1==null)
            {
                throw new IllegalStateException();
            }
            return constant1;
        }
    }
    

    通过这种方式,您可以在常量类中添加一个协议:常量必须在第一次使用之前被初始化一次 - 并且只需要一次。

    【讨论】:

      【解决方案3】:

      使用singleton!

      这里的想法是使用单例对象来保存单个实例。只要您需要创建该实例,就可以在运行时创建它。

      你可以让实例成为你想要的任何东西。一旦初始化,就不能再更改。最终的、静态的,并且在运行后可初始化。

      您可以阅读一下如何使用singletons here

      编辑:

      正如 cmets 中所指出的,一定要了解单例的缺点。如果您有兴趣,可以通过popular post 获取更多信息。

      【讨论】:

      • 但首先阅读这里:What's so bad about singletons? 我认为它们的缺点往往超过它们的好处,特别是如果您发现自己测试的代码依赖于单例。
      • @TobiaTesan 是的,Spring 单例 bean 太糟糕了……单例是好是坏,这是有争议的,需要根据具体情况进行分析。软件中没有绝对的规则。
      • @FedericoPeraltaSchaffner 谁曾说过不一样? :-) 我仍然认为重要的是要指出该模式有缺点(或者,更恰当地说,有 situations 不是一个好主意)来抵消 OP 的建议并确保它不是盲目跟风。
      • @TobiaTesan 你说得对,我的评论可能有点太苛刻了。如果是这样的话,我很抱歉。我同意您对单例模式的担忧。只是有时它非常有用,尽管它有缺点;)
      • 我意识到这是两周前的事了,但感谢您将链接添加到单身人士的缺点。我将在我的回答中为未来的读者提供指向该链接的链接,以免它在 cmets 中被浏览。 :)
      猜你喜欢
      • 2012-06-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-02
      • 2013-07-09
      • 2011-05-23
      • 1970-01-01
      相关资源
      最近更新 更多