1. 程式人生 > 其它 >linux執行緒私有資料---TSD

linux執行緒私有資料---TSD

final

最終的

  • 修飾類:表示類不可被繼承

  • 修飾方法:表示方法不可被子類覆蓋,但是可以過載

  • 修飾變數:表示變數—旦被賦值就不可以更改它的值。

(1)修飾成員變數

·如果final修飾的是類變數,只能在靜態初始化塊中指定初始值或者宣告該類變數時指定初始值。

·如果final修飾的是成員變數,可以在非靜態初始化塊、宣告該變數或者構造器中執行初始值。

(2)修飾區域性變數

系統不會為區域性變數進行初始化,區域性變數必須由程式設計師顯示初始化。因此使用final修飾區域性變數時,即可以在定義時指定預設值(後面的程式碼不能對變數再賦值),也可以不指定預設值,而在後面的程式碼中對final變數賦初值(僅一次)

(3)修飾基本型別資料和引用型別資料

  • 如果是基本資料型別的變數,則其數值一旦在初始化之後便不能更改;
  • 如果是引用型別的變數,則在對其初始化之後便不能再讓其指向另一個物件。但是引用的值是可變的。
public c1ass Fina1ReferenceTest{
    public static void main(){
        final int[] iArr={1,2,3,4};
        iArr[2]=-3;//合法
        iArr=nu11;//非法,對iArr不能重新賦值
        final Person p = new Person(25);p.setAge(24);//合法
        p=nu11;//非法
    }
}

為什麼區域性內部類和匿名內部類只能訪問區域性final變數?

編譯之後會生成兩個class檔案,Test.class Test1.class

public class Test {
    public static void main(String[] args){
    }
        //區域性fina1變數a,b
        public void test(final int b) {
            final int a = 10;
            /匿名內部類
            new Thread(){
                public void run() {
                    system. out.print7n(a) ;
                    system.out.print1n(b);
                };
            }.start();
        }
}

class outclass {
    private int age = 12;
    pub1ic void outPrint(final int x) {
        class Inclass {
            public void InPrint(){
                system.out.print1n(x);
                system.out.print1n(age);
            }
        }
    	new Inc1ass().InPrint();
    }
}

首先需要知道的一點是:內部類和外部類是處於同一個級別的,內部類不會因為定義在方法中就會隨著方法的執行完畢就被銷燬。

這裡就會產生問題:當外部類的方法結束時,區域性變數就會被銷燬了,但是內部類物件可能還存在(只有沒有人再引用它時,才會死亡)。這裡就出現了一個矛盾:內部類物件訪問了一個不存在的變數。為了解決這個問題,就將區域性變數複製了一份作為內部類的成員變數,這樣當局部變數死亡後,內部類仍可以訪問它,實際訪問的是區域性變數的"copy"。這樣就好像延長了區域性變數的生命週期

將區域性變數複製為內部類的成員變數時,必須保證這兩個變數是一樣的,也就是如果我們在內部類中修改了成員變數,方法中的區域性變數也得跟著改變,怎麼解決問題呢?

就將區域性變數設定為final,對它初始化後,我就不讓你再去修改這個變數,就保證了內部類的成員變數和方法的區域性變數的一致性。這實際上也是一種妥協。

使得區域性變數與內部類內建立的拷貝保持一致。