Java靜態(tài)和非靜態(tài)成員變量初始化過程解析
這篇文章主要介紹了Java靜態(tài)和非靜態(tài)成員變量初始化過程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
Java中非靜態(tài)成員變量、靜態(tài)成員變量的初始化時機。
非靜態(tài)變量
我們在這里分析三種結(jié)構(gòu),著重分析這三種結(jié)構(gòu)的初始化順序:
- 成員變量初始化語句;
- 成員變量初始化塊;
- 構(gòu)造函數(shù);
示例一:
public class MyTest {
private String name = "wei.hu";
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#輸出
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna
示例二:
public class MyTest {
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
private String name = "wei.hu";
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#結(jié)果(與示例一相同)
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: wei.hu
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: chouchou
After the name was modified: mengna
mengna
示例三:
public class MyTest {
public MyTest(String name) {
System.out.println("This is constructor. Will assign the variable name to: " + name + ".");
System.out.println("Before the name was modified: " + this.name);
this.name = name;
System.out.println("After the name was modified: " + this.name);
}
{
System.out.println("This is initialize block. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + this.name);
this.name = "chouchou";
System.out.println("After the name was modified: " + this.name);
}
private String name = "wei.hu";
public String getName() {
return name;
}
public static void main(String[] args) {
MyTest myTest = new MyTest("mengna");
System.out.println(myTest.getName());
}
}
#結(jié)果
This is initialize block. Will assign the variable name to: chouchou
Before the name was modified: null
After the name was modified: chouchou
This is constructor. Will assign the variable name to: mengna.
Before the name was modified: wei.hu
After the name was modified: mengna
mengna
分析:
注意本示例的結(jié)果與上面兩個示例的結(jié)果不同。
1、當(dāng)我們想將成員變量name賦值為chouchou之前,發(fā)現(xiàn)this.name為null。也就是說初始化語句沒有先執(zhí)行,而是先執(zhí)行了初始化塊;
2、當(dāng)在執(zhí)行構(gòu)造函數(shù)時,我們想將成員變量name賦值為mengna,發(fā)現(xiàn)賦值之前,this.name不再是chouchou,而是wei.hu,這說明了什么?
因為初始化塊先執(zhí)行,如果緊接著執(zhí)行構(gòu)造函數(shù)的話,那么在構(gòu)造函數(shù)賦值語句執(zhí)行之前,this.name應(yīng)該是chouchou才對。但是在構(gòu)造函數(shù)賦值語句執(zhí)行之前,this.name的值變成了wei.hu,那么足以證明:
1)初始化塊先執(zhí)行;
2)下來執(zhí)行了初始化語句;
3)最后執(zhí)行了構(gòu)造函數(shù);
結(jié)論:
通過上面三個示例,我們可以發(fā)現(xiàn),對于非靜態(tài)的成員變量:
初始化語句、初始化塊,總是先于構(gòu)造函數(shù)執(zhí)行;
初始化語句、初始化塊的和執(zhí)行順序,取決于 初始化語句、初始化塊在代碼中的書寫順序。寫在上面的先執(zhí)行。
靜態(tài)變量
我們在這里也分析三種結(jié)構(gòu):
- 靜態(tài)初始化語句;
- 靜態(tài)初始化塊;
- 構(gòu)造函數(shù);
示例一:
public class MyTest {
public static String name = "wei.hu";
public MyTest() {
System.out.println("This is constructor. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + name);
name = "chouchou";
System.out.println("After the name was modified: " + name);
}
static {
System.out.println("This is static initialize block. Will assign the variable name to: mengna");
System.out.println("Before the name was modified: " + name);
name = "mengna";
System.out.println("After the name was modified: " + name);
}
public static void main(String[] args) {
System.out.println(MyTest.name);
}
}
#結(jié)果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: wei.hu
After the name was modified: mengna
mengna
分析:
通過打印輸出,我們發(fā)現(xiàn)在執(zhí)行靜態(tài)初始快之前,靜態(tài)變量name已經(jīng)初始化為wei.hu了。也就是說:
1、靜態(tài)初始化語句先執(zhí)行;
2、下來執(zhí)行靜態(tài)初始化塊;
3、構(gòu)造函數(shù)未執(zhí)行;
---------------------
示例二:
public class MyTest {
public MyTest() {
System.out.println("This is constructor. Will assign the variable name to: chouchou");
System.out.println("Before the name was modified: " + MyTest.name);
name = "chouchou";
System.out.println("After the name was modified: " + MyTest.name);
}
static {
System.out.println("This is static initialize block. Will assign the variable name to: mengna");
System.out.println("Before the name was modified: " + MyTest.name);
name = "mengna";
System.out.println("After the name was modified: " + MyTest.name);
}
public static String name = "wei.hu";
public static void main(String[] args) {
System.out.println(MyTest.name);
}
}
#結(jié)果
This is static initialize block. Will assign the variable name to: mengna
Before the name was modified: null
After the name was modified: mengna
wei.hu
分析:
初始化塊在對靜態(tài)變量賦值之前,發(fā)現(xiàn)MyTest.name的值為空。 在最后打印出MyTest.name時,發(fā)現(xiàn)輸出的值是wei.hu,而不是mengna。也就是說,在初始化塊執(zhí)行之后,執(zhí)行了靜態(tài)初始化語句。
1、先執(zhí)行靜態(tài)初始化塊;
2、再執(zhí)行靜態(tài)初始化語句;
3、構(gòu)造函數(shù)未執(zhí)行;
---------------------
結(jié)論:
對于靜態(tài)字段,初始化有如下規(guī)則:
1. 若靜態(tài)初始化語句在前,靜態(tài)代碼塊在后,則先執(zhí)行靜態(tài)初始化語句;
2. 若靜態(tài)代碼塊在前,靜態(tài)初始化語句在后,則先執(zhí)行靜態(tài)代碼塊;
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
spring boot 實現(xiàn)配置多個DispatcherServlet最簡單方式
這篇文章主要介紹了spring boot 實現(xiàn)配置多個DispatcherServlet最簡單方式,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
SpringMVC中的@RequestMapping注解的使用詳細(xì)教程
@RequestMapping注解的作用就是將請求和處理請求的控制器方法關(guān)聯(lián)起來,建立映射關(guān)系,本文主要來和大家詳細(xì)講講它的具體使用,感興趣的可以了解一下2023-07-07
Java分別利用深度優(yōu)先和廣度優(yōu)先求解迷宮路徑
這篇文章主要為大家詳細(xì)介紹了Java如何利用深度優(yōu)先的非遞歸遍歷方法和廣度優(yōu)先的遍歷方法實現(xiàn)求解迷宮路徑,文中的示例代碼講解詳細(xì),需要的可以參考一下2022-08-08

