[轉]java static final 初始化


http://tanbing1986411.blog.163.com/blog/static/7259798220103610224434/

java static final 初始化

1.static修飾(類變量)一個屬性字段,那么這個屬性字段將成為類本身的資源,public修飾為共有的,可以在類的外部通過test.a來訪問此屬性;在類內部任何地方可以使用.如果被修飾為private私有,那么只能在類內部使用. 

  1. public class Test{
  2. public static int a;//類連接時,默認初始為0,而又無類變量初始化語句或者靜態初始化語句,故此類無類初始化方法<clinit>
  3. private Test(){
  4. a=0;//類實例化時候調用
  5. }
  6. }

如果屬性被修飾為static靜態類資源,那么這個字段永遠只有一個,也就是說不管你new test()多少個類的對象,操作的永遠都只是屬於類的那一塊內存資源.例如: 

  1. Test t1=new Test();
  2. t1.a=10;
  3. Test t2=new Test();
  4. System.out.println(t1.a);
  5. System.out.println(t2.a);
  6. System.out.println(Test.a);

代碼 結果是3個10

2.final 用於聲明屬性(常量),方法和類,分別表示屬性一旦被分配內存空間就必須初始化不會有默認初始化,局部變量也是如此,默認初始化只有普通的非final屬性,對於static(無final修飾)類變量,類連接時候有默認初始化,對於像private int a;在類實例化時,構造函數默認初始為0,總之,變量必須初始化后方可用,這是java的安全之一,例如,對象引用初始化后不會引用錯誤的內存空間),並且以后不可變;方法一旦定義必須有實現代碼並且子類里不可被覆蓋,類一旦定義不能被定義為抽象類或是接口,因為不可被繼承。


3. 被final修飾而沒有被static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化

對於接口,由於只能包含常量和方法(必須wei 
a.在它被聲明的時候賦值,例: 

  1. public class Test{
  2. public final int a=0;
  3. private Test(){
  4. }
  5. }

b.在構造函數里初始化

例如:

  1. public class Test{
  2. public final int a;
  3. private Test(){
  4. a=0;
  5. }
  6. }

c、在非靜態塊里

public class Test{

         private final int a;

        {

             a=9;

          }

}
解釋:當這個屬性被修飾為final,而非static的時候,它屬於類的實例對象的資源(實例常量),當類被加載進內存的時候這個屬性並沒有給其分配內存空間,而只是 定義了一個變量a,只有當類被實例化的時候這個屬性才被分配內存空間,而實例化的時候同時執行了構造函數,所以屬性被初始化了,也就符合了當它被分配內存 空間的時候就需要初始化,以后不再改變的條件.

4、 被static修飾而沒有被final修飾的類的屬性變量只能在兩種情況下初始化:(可以不初始化

如果初始化,就生成類初始化函數<clinit>,否則沒有
a.在它被聲明的時候賦值,例:

  1. public class Test{
  2. public static l int a=8;
  3. private Test(){
  4. }
  5. }

b.在靜態或非靜態快里初始化

  1. public class Test{
  2. public static l int a;
  3. static{a=50;}
  4. private Test(){
  5. }
  6. }

解釋:
當類的屬性被同時被修飾為static時候,他屬於類的資源(類變量),在類加載后,進行連接時候,分三步: 先驗證;然后准備,准備時,先分配內存,接着默認初始化;可以進行解析。最后,進行類初始化,類初始化前,必須保證它的父類已經初始化了,所以最先初始化的是超類,對於接口,不必初始其父接口。類初始化時,它把類變量初始化語句及靜態初始化語句放到類初始化方法中,所以,如果無此兩種語句,也就沒<clinit>類初始化方法,而構造函數是在當類 被實例化的時候才會執行,所以用構造函數,這時候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候執行,且只執行這一次,所以在 static塊中可以被初始化.

5.同時被final和static修飾的類的屬性變量只能在兩種情況下初始化:(必須初始化)

a.在它被定義的時候,例: 

  1. public class Test{
  2. public final static int a=5;
  3. private Test(){
  4. }
  5. }

b.在類的靜態塊里初始化,例: 

  1. public class Test{
  2. public final static int a;
  3. static{
  4. a=0;
  5. }
  6. }

c、特別對於初始化時候調用拋出異常的構造函數,初始時候注意,特別是在實現單例模式時(只能這么初始化)
如:
class A

private final static A a;
static
{
try
{
a=new A();
}catch(Exception e)
{
throws new RuntimeException(e);          //必須有,不然不能完成常量的正確初始化
}
}
private A() throws Exception{}
}
解釋:

當類的屬性被同時被修飾為static和final的時候,他屬於類的資源(類常量),那么就是類在被加載進內存的時候(也就是應用程 序啟動的時候)就要已經為此屬性分配了內存,所以此時屬性已經存在,它又被final修飾,所以必須在屬性定義了以后就給其初始化值.而構造函數是在當類 被實例化的時候才會執行,所以用構造函數,這時候這個屬性沒有被初始化.程序就會報錯.而static塊是類被加載的時候執行,且只執行這一次,所以在 static塊中可以被初始化.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM