深入理解final變量的初始化
更新時間:2013年06月04日 16:47:21 作者:
本篇文章是對final變量的初始化進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
final變量的初始化位置
一是其定義處,也就是說在final變量定義時直接給其賦值,
二是在構(gòu)造函數(shù)中。而且在Java1.1以前,只能是在定義時給值。
三是在初如化代碼塊中{} 或者 static{}
public class InitOrder {
{
System.out.println("before---field");
//System.out.println("d1="+d1);
d1 = 3;
//System.out.println("d1="+d1);
}
static {
System.out.println("before---static field");
//System.out.println("d2="+d2);
d2 = 3;
//System.out.println("d2="+d2);
}
final int a1 = 1;
final int b1;
final int c1;
final int d1;
//final int e1;
static final int a2 = 1;
//static final int b2;
static final int c2;
static final int d2;
//static final int e2;
{
System.out.println("after---field");
//System.out.println("c1="+c1);
c1 = 4;
System.out.println("c1="+c1);
//e2 =3;
}
static {
System.out.println("after---static field");
//System.out.println("c2="+c2);
c2 = 4;
System.out.println("c2="+c2);
//e1 = 3;
}
public InitOrder() {
b1 = 2;
//b2 = 2;
}
public static void main(String[] args) {
InitOrder order = new InitOrder();
System.out.println("c1="+order.c1);
System.out.println("c2="+order.c2);
System.out.println("d1="+order.d1);
System.out.println("d2="+order.d2);
}
}
說明:上述所有注釋皆為有語法錯誤
輸出結(jié)果:
before---static field
after---static field
c2=4
before---field
after---field
c1=4
c1=4
c2=4
d1=3
d2=3
結(jié)果分析:
1. 對比a1,a2基本沒有什么問題,定義時就初始化
2. 對比b1,b2在構(gòu)造函數(shù)中初始化,b1沒有問題,b2有問題,這是因為構(gòu)造函數(shù)的調(diào)用在靜態(tài)變量的后面而b2是靜態(tài)的,所以會報錯
3. 對比c1,d1發(fā)現(xiàn)初始化沒有問題,有問題的是使用輸出語句。對于d1在初始化代碼塊中不論在哪加輸出語句都會報錯,這是因為d1所在的初始化代碼塊位置在變量d1定義的前面,而java中變量的初始化順序是見Java中變量的初始化順序, 普通變量和初始化代碼塊的初始化順序是按照位置的先后的所以輸出用到了d1變量,所以出錯,但有一點我不明白,為什么在這里初始化d1不報錯,而且在main函數(shù)中還可以調(diào)用它,難道這個也要去看一下java虛擬機?對于c1在后面加輸出語句沒有問題。前面加有問題很好理解,就是大之前沒有被初始化.
4. 對于c2,d2是和3同樣的道理
5. 對于e1放在靜態(tài)代碼塊中顯然不行,因為靜態(tài)代碼塊最先加載,那時e1還沒有加
6. 對于e2也是,普通代碼塊的加載要晚于靜態(tài)變量,所以也是不行的。
一是其定義處,也就是說在final變量定義時直接給其賦值,
二是在構(gòu)造函數(shù)中。而且在Java1.1以前,只能是在定義時給值。
三是在初如化代碼塊中{} 或者 static{}
復(fù)制代碼 代碼如下:
public class InitOrder {
{
System.out.println("before---field");
//System.out.println("d1="+d1);
d1 = 3;
//System.out.println("d1="+d1);
}
static {
System.out.println("before---static field");
//System.out.println("d2="+d2);
d2 = 3;
//System.out.println("d2="+d2);
}
final int a1 = 1;
final int b1;
final int c1;
final int d1;
//final int e1;
static final int a2 = 1;
//static final int b2;
static final int c2;
static final int d2;
//static final int e2;
{
System.out.println("after---field");
//System.out.println("c1="+c1);
c1 = 4;
System.out.println("c1="+c1);
//e2 =3;
}
static {
System.out.println("after---static field");
//System.out.println("c2="+c2);
c2 = 4;
System.out.println("c2="+c2);
//e1 = 3;
}
public InitOrder() {
b1 = 2;
//b2 = 2;
}
public static void main(String[] args) {
InitOrder order = new InitOrder();
System.out.println("c1="+order.c1);
System.out.println("c2="+order.c2);
System.out.println("d1="+order.d1);
System.out.println("d2="+order.d2);
}
}
說明:上述所有注釋皆為有語法錯誤
輸出結(jié)果:
before---static field
after---static field
c2=4
before---field
after---field
c1=4
c1=4
c2=4
d1=3
d2=3
結(jié)果分析:
1. 對比a1,a2基本沒有什么問題,定義時就初始化
2. 對比b1,b2在構(gòu)造函數(shù)中初始化,b1沒有問題,b2有問題,這是因為構(gòu)造函數(shù)的調(diào)用在靜態(tài)變量的后面而b2是靜態(tài)的,所以會報錯
3. 對比c1,d1發(fā)現(xiàn)初始化沒有問題,有問題的是使用輸出語句。對于d1在初始化代碼塊中不論在哪加輸出語句都會報錯,這是因為d1所在的初始化代碼塊位置在變量d1定義的前面,而java中變量的初始化順序是見Java中變量的初始化順序, 普通變量和初始化代碼塊的初始化順序是按照位置的先后的所以輸出用到了d1變量,所以出錯,但有一點我不明白,為什么在這里初始化d1不報錯,而且在main函數(shù)中還可以調(diào)用它,難道這個也要去看一下java虛擬機?對于c1在后面加輸出語句沒有問題。前面加有問題很好理解,就是大之前沒有被初始化.
4. 對于c2,d2是和3同樣的道理
5. 對于e1放在靜態(tài)代碼塊中顯然不行,因為靜態(tài)代碼塊最先加載,那時e1還沒有加
6. 對于e2也是,普通代碼塊的加載要晚于靜態(tài)變量,所以也是不行的。
相關(guān)文章
創(chuàng)建Spring Boot項目的幾種方式總結(jié)(推薦)
這篇文章主要介紹了創(chuàng)建Spring Boot項目的幾種方式總結(jié)(推薦),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07Java7到Java17之Switch語句進(jìn)化史示例詳解
這篇文章主要為大家介紹了Java7到Java17之Switch語句進(jìn)化史示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01學(xué)習(xí)Java設(shè)計模式之觀察者模式
這篇文章主要為大家介紹了Java設(shè)計模式中的觀察者模式,對Java設(shè)計模式感興趣的小伙伴們可以參考一下2016-01-01使用fastjson中的JSONPath處理json數(shù)據(jù)的方法
這篇文章主要介紹了使用fastjson中的JSONPath處理json數(shù)據(jù)的方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04MybatisPlus使用Mybatis的XML的動態(tài)SQL的功能實現(xiàn)多表查詢
本文主要介紹了MybatisPlus使用Mybatis的XML的動態(tài)SQL的功能實現(xiàn)多表查詢,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-11-11