7

在使用类名访问最终静态变量时,为什么没有在 java 中处理静态块?

class Foo {
  public static final int BAR;
  static {
    System.out.println("Hello");
    }
  }
class Baz {
  public static void quux() {
    System.out.println(Foo.BAR);
  }
}
4

2 回答 2

11

有时会 - 这取决于变量是否实际上是常量

  • 它必须是字符串或原始变量(可能是具有空值的任何其他类;我必须检查)
  • 初始化表达式必须是常量表达式

如果是这种情况,对变量的任何引用都会有效地转换为值。所以在这段代码中:

class Foo {
    public static final int BAR = 5;
}

class Baz {
    public static void quux() {
        System.out.println(Foo.BAR);
    }
}

方法 inBaz被编译成与以下相同的代码:

public static void quux() {
    System.out.println(5);
}

Foo.BAR字节码中没有留下的提示,因此Foo不需要在方法执行时进行初始化。

如果你想防止这种情况发生,你总是让它不被变量初始化器中的常量表达式初始化。例如:

class Foo {
    public static final int BAR;

    static {
        BAR = 5;
    }
}

class Baz {
    public static void quux() {
        System.out.println(Foo.BAR);
    }
}

就编译器而言,这足以使其Foo.BAR不算作常数。

于 2013-04-06T21:44:57.997 回答
0

静态块只会在您的类加载时执行。这将在以下情况下完成:

  1. 最初当您的程序启动时
  2. 如果您在运行时手动加载您的类

    例如:使用 Class.forName("Foo"))

于 2018-08-28T05:14:34.500 回答