Reading 1: Static Checking > Mutating Values Vs. Reassigning Variables
原文地址:https://courses.edx.org/courses/course-v1:MITx+6.005.1x+3T2016/courseware/Readings_Videos/01-Static-Checking/
可變值對比重賦值變量
畫下運行時發(fā)生事情的圖片對我們明白一些潛在問題來說很有幫助.快照圖代表了一個程序運行時的狀態(tài).
用其最簡單的形式,一個快照圖顯示一個變量以及用一個剪頭指向其值.一個值可能是一個基本變量比如說int,可以簡單地寫一個數(shù)字,又或者是一個對象例如String或者ArrayList,這用一個圓包裹著它的類型.一個對象的值往往有其內(nèi)在的變量以及箭頭指向其值.例如,在冰雹序列代碼的某個從n=3開始的地方,一個快照圖可能如上圖所示.
盡管這門課圖片的例子運用Java,這個標(biāo)記可以用到其他任何現(xiàn)代的語言,例如Python,C++,Ruby.
快照圖給了我們一個直觀的方式去可視化改變變量和改變值的區(qū)別:
- 當(dāng)你給一個變量賦值時,你在改變變量剪頭的指向.你可以使它指向一個不同的值.
intn =3;n = 3*n + 1;n = n/2;
- 當(dāng)我們改變一個可變值的內(nèi)容時--比如一個集合或者一個列表--你在改變一個值的內(nèi)在引用.這稱為改變值.
Listlist=newArrayList();list.add(3);list.add(5);list.set(0, 9);
重賦值和不可變值
例如,我們有一個String類型的變量s,我們可以把它的值從'a'重賦值為'ab'.
String s ="a";
s = s +"b";
String是一個不可變類型的例子,一個類型其值至創(chuàng)造后再也不能改變.不可變性是本門課的一個主要的設(shè)計原則.我們將在閱讀材料中更多的談到這一點.
不可變對象(它們設(shè)計者的目的是用它們代表相同的值)在快照圖中用兩個邊界表示,類似我們圖表中的String類型.
可變的值
相反,StringBuilder(另一個Java自帶的類型)是一個可變的對象代表了一串對象.它有方法去改變它的值.
StringBuilder sb =newStringBuilder("a");
sb.append("b");
這兩個快照圖看起來很不一樣,哪一個是好的:可變和不可變的差別在使代碼遠(yuǎn)離bug的過程中扮演了重要的角色.
不可變引用
Java還給了我們不可變的引用:變量賦值了一次就不用再賦值了.為了引用不可變,用final關(guān)鍵詞聲明它:finalintn =5;
如果你的Java編譯器不確定你的final變量將在運行時只賦值一次,它將產(chǎn)生一個編譯錯誤.因此final給你了一個靜態(tài)的不可變引用的檢測.
在快照圖中,一個不可變的引用將用雙線的箭頭.
注意到我們可以有一個不可變的引用引用到一個可變的值.例如:final StringBuilder sb;這意味著這個StringBuilder的值可以改變,但是sb的箭頭不會改變;它永遠(yuǎn)指向同一個StringBuilder對象.
我們可以永遠(yuǎn)有一個可變的引用到一個不可變的值.比如String s,s變量的值可以改變因為它可以重指向不同的對象.
在聲明一個方法的參數(shù)和盡可能多的本地變量時,用final是一個很好的實踐.類似變量的類型,這些聲明是非常重要的文檔,對讀代碼很有用以及編譯器可以靜態(tài)檢測.
這里有我們的冰雹序列的兩個變量:我們可以將它們聲明為final嗎?