Java 中靜態代碼塊初始化問題測試 原創
情況一:變量是 static final 修飾的“編譯期常量”,如 public static final String a = "JD";
public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static final String a = "JD";
static {
System.out.print("OK");
}
}
參考答案
``` JD ```
情況二:變量是 static final 修飾的“非編譯期常量”,如 public static final String a = new String("JD");
public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static final String a = new String("JD");
static {
System.out.print("OK");
}
}
參考答案
``` OKJD ```
情況三:static 變量域不是 final,如 public static String a = "JD";
public class Test {
public static void main(String[] args) {
System.out.println(Test2.a);
}
}
class Test2 {
public static String a = "JD";
static {
System.out.print("OK");
}
}
參考答案
``` OKJD ```
情況四:繼承是JAVA語言的一個特性,針對類的繼承,虛擬機會如何進行父類和子類的初始化加載呢?
public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
public static final String c = "C";
}
參考答案
``` C ```
public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
public static String c = "C";
}
參考答案
``` ABC ```
public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
public static String c = new String("C");
}
參考答案
``` ABC ```
public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
}
class B extends A {
static {
System.out.print("B");
}
public static final String c = new String("C");
}
參考答案
``` ABC ```
public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
// 測試:只能選擇其中一種一條語句
// public static final String c = "C";
// public static String c = "C";
// public static final String c = new String("C");
public static String c = new String("C");
}
class B extends A {
static {
System.out.print("B");
}
}
參考答案
``` public class Test {
public static void main(String[] args) {
System.out.print(B.c);
}
}
class A {
static {
System.out.print("A");
}
// 測試:只能選擇其中一種一條語句
// public static final String c = "C"; // C
// public static String c = "C"; // AC
// public static final String c = new String("C"); // AC
public static String c = new String("C"); // AC
}
class B extends A {
static {
System.out.print("B");
}
}
</div>
<blockquote><b>總結:</b>
1、如果一個 <b>static final</b> 變量是<b>"編譯期常量"</b>,就像 <i style="color:red;">public static final String a = "JD";</i>那樣,那么這個值不需要對 Test2 類進行初始化就可以讀取。
2、但是,如果只是將一個變量的域設置為 static 和 final 的,那<b>不足以</b>確保這種行為。例如,對 <i style="color:red;">public static final String a = new String("JD");</i>的訪問將強制對 Test2 類進行初始化,因為<b>它不是</b>一個"編譯期常量"。
3、如果一個 static 變量域不是 final,那么在對它進行訪問時,總是要求在它被讀取之前,要先進行<b>鏈接</b> (為這個域分配存儲空間) 和<b>初始化</b> (初始化該存儲空間) 就像 <i style="color:red;">public static String a = "JD";</i>。
</blockquote>
**參考鏈接**
* [https://blog.csdn.net/dreamzuora/article/details/80188708](https://blog.csdn.net/dreamzuora/article/details/80188708)