[英]What's the proper way or underlying difference of initializing a static variable in one way or another in Java language?
我对初始化 static 变量的正确方法有点怀疑。
我意识到我可以在定义时直接为static
变量赋值,例如:
public class MyClass {
// Direct initialization
public static int counter = 0;
另外,我看到您可以使用static
块,例如:
public class MyClass {
public static int counter;
static {
counter = 0;
}
}
甚至,我惊讶地看到,您还可以从 class 构造函数访问static
变量并从那里设置一个值,例如:
public class MyClass {
public static int counter;
public MyClass() {
this.counter = 0;
}
public MyClass( int a ) {
this.counter = a;
}
}
我的问题是:在处理 static 变量时,使用一种或另一种类型的初始化的正确方法或潜在区别是什么?
我还编写并执行了以下代码,因此我可以意识到变量是如何随着程序执行而被修改的。
public class StaticVariable {
static int a = 0;
public StaticVariable( int b ) {
// The constructor parameter b is ignored
System.out.println( "[Inside 1-parameter constructor] Current value of \"a\": " + a + " ." );
System.out.println( "[Inside 1-parameter constructor] Value of \"a\" was increased in one ..." );
a++;
}
public StaticVariable() {
System.out.println( "[Inside parameterless constructor] Current value of \"a\": " + a + " ." );
System.out.println( "[Inside parameterless constructor] Value of \"a\" was increased in one ..." );
a++;
}
static {
System.out.println( "[Inside static block] Initial value of \"a\": " + a + " ." );
System.out.println( "[Inside static block] Value of \"a\" was increased in one ..." );
a++;
}
public static void main( String[] args ) {
System.out.println( "[main method] Current value of \"a\": " + StaticVariable.a + " ." );
StaticVariable object = new StaticVariable();
System.out.println( "[main method] Current value of \"a\": " + StaticVariable.a + " ." );
StaticVariable object2 = new StaticVariable( 10 );
System.out.println( "[main method] Current value of \"a\": " + StaticVariable.a );
System.out.println( "[main method] Directly setting value of \"a\" with 560" );
StaticVariable.a = 560;
System.out.println( "Updated value of \"a\": " + StaticVariable.a );
}
}
提前致谢。
简短回答:如果您需要使用static
块,请仅使用它们。
在您的前两个示例中,没有语义或性能差异,编写代码的正确方法是简单的方法。
第三个例子在语义上是不同的。 设置器实际上并未初始化 static 变量。 它正在重新初始化变量。 (您可以在调用 setter 之前调用 getter,这将向您显示真正的初始值;即零。)
使用 setter 没有任何问题(根据您的第三个示例),但它正在做一些不同的事情。 如果您只想简单地初始化为固定值,请不要这样做。 用简单的方法来做。
(最后一个例子似乎不恰当,所以我将忽略它。)
在某些情况下,不可能在单个表达式中执行必要的初始化。 (例如,可能需要执行一系列语句来填充 object,或捕获并处理异常,或处理相互引用的final
对象1。 )在这些情况下, static
块是一种可能的解决方案。
前两种方法之间是否存在“潜在差异”?
我不这么认为。
static Foo foo = <expression>; // where this is legal Java code
在语义上 100% 等价于:
static Foo foo;
static {
foo = <expression>;
}
只是有些事情可以用 static 块做,而用简单的初始化程序是做不到的。 static 块可能比单个赋值语句更复杂。
1 - 我在这里的术语“松散”。 它实际上是final
的变量而不是对象。
第一种和第二种方法是等效的。 通常,您会发现第一种方法对于单个变量的简单初始化更为常见。 但有时 static 块中的初始化可以方便更复杂的情况,例如,将几个元素添加到一个static
变量的集合中,如下所示:
static List<String> list;
static {
list = new ArrayList<>();
list.add("hello");
list.add("world");
}
至于您描述的第三个选项,即在实例化期间进行初始化,它将在每次创建 class 的新实例时重新初始化 static 变量。 可能最好避免这种情况。 我想不出我想要的情况。
Static 字段属于 class 而不是对象,因此在构造函数中设置它们的值并不是一个好主意。 因此,每次创建 object 时,它都可能会影响代码的其他部分。
在直接设置或在 static 块中设置中,我个人更喜欢直接设置,因为它更清晰易读。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.