【问题标题】:Should immutable, final variables always be static? [duplicate]不可变的最终变量是否应该始终是静态的? [复制]
【发布时间】:2018-08-23 05:25:55
【问题描述】:

在java中,如果一个变量是不可变的并且是final的,那么它应该是一个静态类变量吗?

我问是因为每次类的实例使用它时创建一个新对象似乎很浪费(因为它总是一样的)。

例子:

每次调用时在方法中创建的变量:

public class SomeClass {

    public void someMethod() {

        final String someRegex = "\\d+";
        final Pattern somePattern = Pattern.compile(someRegex);

        ...

    }

}

变量创建一次:

public class SomeClass {

    private final static String someRegex = "\\d+";
    private final static Pattern somePattern = Pattern.compile(someRegex);

    public void someMethod() {

        ...

    }

}

是否总是最好使用后一种代码?

这个答案似乎表明最好使用后一个代码:How can I initialize a String array with length 0 in Java?

【问题讨论】:

  • 你也可以有一个最终实例变量,每个实例都不同。

标签: java


【解决方案1】:

不,绝对不是。

class MyIntegerContainer{
    private final int x;
    public MyIntegerContainer(int x){
        this.x = x;
    }
}

如果您将最终的x 设置为不可变的静态,那么MyIntegerContainer 的所有实例将共享x 的相同值,这不会构成一个非常好的数据容器。

【讨论】:

  • 对,static 用于类变量,在类的所有实例中值都相同。如果这是您想要的,请使用staticfinal 实例变量很有用而且很常见。
  • 与@markspace 注释一起使用,例如,如果您想要一个常量,最好设为public static final。 (仅当其他类需要该常量时才公开)
  • 我应该改写问题,这不是我指的情况。
  • 关于您的示例:在第一种情况下,someRegexsomePattern 两个变量是局部变量,这意味着一旦方法块具有完成并将很快被 GC 清除。在第二种情况下,只要存在类的实例,就会将内存分配给您的类变量并在所有实例之间共享。如果有很多实例并且someMethod方法在不同的线程中同时运行,那么第二种情况将是有益的,否则几乎没有区别。
【解决方案2】:

最终这取决于您对这些变量的处理方式。

如果变量只在该特定方法内有生命周期——也就是说,没有其他东西永远需要看到它或使用这些值——然后声明它们里面的方法是恰当和正确的。让它比它需要的更明显只会增加未来维护者(包括你自己)的困惑。

如果变量的生命周期在类之外,则可能将其声明为static。在常量或变量本身不存储任何状态的情况下尤其如此。

如果它不是常量或在类之外没有任何用途,则保持它为非静态和私有的。

【讨论】:

  • 这里的答案:stackoverflow.com/questions/1665834/… 建议如果你有一个不可变的对象打算重用,你不妨将其设为静态。我误会了吗?
  • @theyuv:这很有意义,因为该变量在该类之外具有生命周期,因此允许它成为该类来自的常量是有意义的。硬性规则很简单:如果您要在多个地方使用它,并且您不想或不能实例化对象的实例来获取它,则将其设为静态。否则,请保持非静态。
  • 谢谢。如果一个不可变的最终变量在同一个类的同一个方法中被重用,它不应该成为一个静态类变量吗?我不应该考虑每次调用该方法时都会重新创建它的事实?...在​​链接的答案中,变量是private。它是如何“在课堂外”使用的。再次感谢。
  • 我认为将其声明为private 是用词不当。它永远不会离开那个班级,也没有孩子会看到它。它可能在那种情况下不应该是静态的。
  • @theyuv 不,您不必担心每次调用该方法时都会重新创建变量,因为正如我在回答中所评论的那样,这些变量是 thread local 并且会在之后被垃圾收集器清除方法执行完毕!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-09-13
  • 1970-01-01
  • 1970-01-01
  • 2011-11-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多