在Java语言中,用一种或多种方式初始化静态变量的正确方式或根本区别是什么?

问题描述 投票:1回答:1

我对初始化静态变量的正确方式有点疑问。

我已经意识到,我可以直接将一个值赋给一个 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 );
    }
}

先谢谢大家了。

java variables static
1个回答
3
投票

简答:只能使用 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 而不是对象。


2
投票

第一种和第二种方法是等价的。通常情况下,对于单个变量的简单初始化,你会发现第一种方法更为常见。但有时在一个块中进行静态初始化对于更复杂的情况也很方便,例如,在一个集合中添加几个元素,而这个集合是个 static 变量,如。

static List<String> list;
static {
  list = new ArrayList<>();
  list.add("hello");
  list.add("world");
}

至于你说的第三个选项 在实例化过程中初始化 每次创建一个新的类实例时 都会重新初始化静态变量 可能最好避免这样做。我想不出在什么情况下我会想要这样做。


1
投票

静态字段属于类而不是对象,所以在构造函数中设置它们的值并不是一个好主意,这样每次创建一个对象都可能会影响到你代码的其他部分。

在直接设置或在静态块中设置中,我个人更倾向于直接设置,因为它更清晰,更容易被其他用户阅读。

© www.soinside.com 2019 - 2024. All rights reserved.