我对初始化静态变量的正确方式有点疑问。
我已经意识到,我可以直接将一个值赋给一个 static
变量的定义,就像在。
public class MyClass {
// Direct initialization
public static int counter = 0;
另外,我还看到你可以用一个 static
块,比如在。
public class MyClass {
public static int counter;
static {
counter = 0;
}
}
甚至,我竟然看到你也可以访问... static
类构造函数中的变量,并从那里给它们设置一个值,比如在。
public class MyClass {
public static int counter;
public MyClass() {
this.counter = 0;
}
public MyClass( int a ) {
this.counter = a;
}
}
我的问题是: 在处理静态变量时,使用一种或另一种类型的初始化有什么正确的方式或根本的区别?
我也写了下面的代码并执行了,所以我可以意识到变量是如何在程序执行过程中被修改的。
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
块,如果你 需要 来使用它们。
在你的前两个例子中,没有语义和性能上的区别,正确的代码写法是简单的方式。
第三个例子在语义上是不同的。 setter实际上并不是在初始化静态变量。 它是 重新初始化 的变量。 (你可以在调用setter之前调用getter,这样你就可以看到变量的 真正 初始值;即零)。)
使用setter并没有错(按照你的第三个例子),但它做的事情是不同的。 如果你只是想对一个固定的值进行简单的初始化,不要用这种方式。 用简单的方式来做。
(最后一个例子似乎并不贴切,所以我将忽略它)。
在某些情况下,不可能在一个表达式中执行必要的初始化。 例如,可能需要执行一系列语句来填充一个对象,或捕获和处理一个异常,或处理 final
对象1 互相引用的。) 在这些情况下,一个 static
块是一种可能的解决方案。
前两种方法有 "本质区别 "吗?
我认为没有。
static Foo foo = <expression>; // where this is legal Java code
是100%语义上等同于。
static Foo foo;
static {
foo = <expression>;
}
只是有些事情你可以用静态块来做 而不是用一个简单的初始化器来做。 静态块可以比单个赋值语句更复杂。
1--我在这里用的是 "宽松 "的术语。 实际上,变量才是 final
而不是对象。
第一种和第二种方法是等价的。通常情况下,对于单个变量的简单初始化,你会发现第一种方法更为常见。但有时在一个块中进行静态初始化对于更复杂的情况也很方便,例如,在一个集合中添加几个元素,而这个集合是个 static
变量,如。
static List<String> list;
static {
list = new ArrayList<>();
list.add("hello");
list.add("world");
}
至于你说的第三个选项 在实例化过程中初始化 每次创建一个新的类实例时 都会重新初始化静态变量 可能最好避免这样做。我想不出在什么情况下我会想要这样做。
静态字段属于类而不是对象,所以在构造函数中设置它们的值并不是一个好主意,这样每次创建一个对象都可能会影响到你代码的其他部分。
在直接设置或在静态块中设置中,我个人更倾向于直接设置,因为它更清晰,更容易被其他用户阅读。