Java 不可变的最终变量是否应该始终是静态的?

Java 不可变的最终变量是否应该始终是静态的?,java,Java,在java中,如果一个变量是不可变的和final的,那么它应该是一个静态类变量吗 我这样问是因为每次类的实例使用一个新对象时创建一个新对象似乎是浪费(因为它总是一样的) 例如: 每次调用方法时在方法中创建的变量: public class SomeClass { public void someMethod() { final String someRegex = "\\d+"; final Pattern somePattern = Pattern.

在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() {

        ...

    }

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


这个答案似乎表明最好使用后一种代码:

最终取决于您对这些变量所做的操作

如果变量在特定方法中只有一个生命周期——也就是说,没有其他任何东西需要看到它或使用这些值——那么在方法中声明它们是适当和正确的。让它变得比需要的更可见只会给未来的维护人员(包括您自己)增加困惑

如果变量的生命周期在类之外,那么将其声明为static是有意义的。对于本身不存储任何状态的常量或变量,情况尤其如此

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

否绝对不是

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

如果将不可变的final
x
设置为static,则
MyIntegerContainer
的所有实例都将共享相同的
x
值,这不适合作为一个非常好的数据容器

您还可以在每个实例中使用不同的最终实例变量。对,
static
用于类变量,这些值在类的所有实例中都是相同的。如果这是您想要的,那么使用
static
final
实例变量很有用,也很常见。例如,如果您想要一个常量,那么最好使用@markspace comment
public static final
。(只有在其他类需要常量时才公开)我应该重写这个问题,这不是我所指的情况。关于你的例子:在第一种情况下,两个变量
someRegex
somePattern
是局部变量,这意味着一旦方法块完成,它们将不在范围内,并且很快将被GC清除。在第二种情况下,只要类的实例存在,内存就会分配给类变量,并在所有实例之间共享。如果有许多实例,并且方法
someMethod
在不同的线程中同时运行,那么第二种情况将是有益的,否则差别不大。这里的答案是:如果您有一个计划重用的不可变对象,您不妨将其设为静态。我误解了吗?@theyuv:这是有意义的,因为该变量在该类之外有生命周期,所以允许它是该类中的常量才有意义。硬性规则很简单:如果您要在多个地方使用它,并且您不想或无法实例化对象的实例来获取它,那么就将其设置为静态。否则,请保持非静态。谢谢。如果在同一类的同一方法中重用了一个不可变的final变量,那么它不应该成为静态类变量吗?我不应该考虑每次调用该方法时都会重新创建的事实……在链接答案中,变量为
private
。“课外”如何使用。再次感谢。我认为宣布它为私有是用词不当的。它永远不会离开那个班,也不会有孩子看到它。在该上下文中,它可能不应该是静态的。@不,您不应该担心每次调用该方法时都会重新创建该变量,因为正如我在回答中所评论的,这些变量是
线程本地的
,并且在该方法完成执行后将被垃圾回收器删除!