標籤:
平時我們學習或許只是簡單按著書來敲代碼,或許只是等待被老師灌輸知識 的習慣,往往是把書中的案例或老師的案例copy過來或是重新敲一遍代碼,看到了效果,oh,nice!然後便不管程式是如何運行起來,沒有深刻理解每一句代碼的意思,瞭解程式編譯的環境。雖然java是一個物件導向的語言,提供許多的方法平時不會用可以查閱jdk協助文檔,但是我們必須去學習它最基本的文法,比如各種基本的資料類型,運算子,控制流程程語句的各種用法。更重要的是java的核心概念,類的繼承,抽象類別,內部類,方法的覆蓋與重載,介面的實現。因此這裡帶你去瞭解這些細節。
先說說容易疏忽的運算子:&和&&。
&和&&都可以用作邏輯與的運算子,表示邏輯與(and),當運算子兩邊的運算式的結果都為true時,整個運算結果才為true,否則,只要有一方為false,則結果為false。 &&還具有短路的功能,即如果第一個運算式為false,則不再計算第二個運算式,例如,對於if(str != null && !str.equals(“”))運算式,當str為null時,後面的運算式不會執行,所以不會出現NullPointerException如果將&&改為&,則會拋出NullPointerException異常。If(x==33 & ++y>0) y會增長,If(x==33 && ++y>0)不會增長。
&還可以用作位元運算符,當&操作符兩邊的運算式不是boolean類型時,&表示按位與操作,我們通常使用0x0f來與一個整數進行&運算,來擷取該整數的最低4個bit位,例如,0x31 & 0x0f的結果為0x01。
除此外基本類型的混淆:int和integer。
int是java提供的8種未經處理資料類型之一。Java為每個原始類型提供了封裝類,Integer是java為int提供的封裝類。int的預設值為0,而Integer的預設值為null,即Integer可以區分出未賦值和值為0的區別,int則無法表達出未賦值的情況,例如,要想表達出沒有參加考試和考試成績為0的區別,則只能使用Integer。在JSP開發中,Integer的預設為null,所以用el運算式在文字框中顯示時,值為空白字串,而int預設的預設值為0,
所以用el運算式在文字框中顯示時,結果為0,所以,int不適合作為web層的表單資料的類型。
在Hibernate中,如果將OID定義為Integer類型,那麼Hibernate就可以根據其值是否為null而判斷一個對象是否是臨時的,如果將OID定義為了int類型,還需要在hbm對應檔中設定其unsaved-value屬性為0。
另外,Integer提供了多個與整數相關的操作方法,例如,將一個字串轉換成整數,Integer中還定義了表示整數的最大值和最小值的常量。
對於“==”和equal方法的混淆:
==操作符專門用來比較兩個變數的值是否相等,也就是用於比較變數所對應的記憶體中所儲存的數值是否相同,要比較兩個基本類型的資料或兩個引用變數是否相等,只能用==操作符。
如果一個變數指向的資料是物件類型的,那麼,這時候涉及了兩塊記憶體,對象本身佔用一塊記憶體(堆記憶體),變數也佔用一塊記憶體,例如Objet obj = new Object();變數obj是一個記憶體,new Object()是另一個記憶體,此時,變數obj所對應的記憶體中儲存的數值就是對象佔用的那塊記憶體的首地址。對於指向物件類型的變數,如果要比較兩個變數是否指向同一個對象,即要看這兩個變數所對應的記憶體中的數值是否相等,這時候就需要用==操作符進行比較。
equals方法是用於比較兩個獨立對象的內容是否相同,就好比去比較兩個人的長相是否相同,它比較的兩個對象是獨立的。例如,對於下面的代碼:
String a=new String("foo");
String b=new String("foo");
兩條new語句建立了兩個對象,然後用a,b這兩個變數分別指向了其中一個對象,這是兩個不同的對象,它們的首地址是不同的,即a和b中儲存的數值是不相同的,所以,運算式a==b將返回false,而這兩個對象中的內容是相同的,所以,運算式a.equals(b)將返回true。
在實際開發中,我們經常要比較傳遞進行來的字串內容是否等,例如,String input = …;input.equals(“quit”),許多人稍不注意就使用==進行比較了,這是錯誤的,隨便從網上找幾個項目實戰的教學視頻看看,裡面就有大量這樣的錯誤。記住,字串的比較基本上都是使用equals方法。
如果一個類沒有自己定義equals方法,那麼它將繼承Object類的equals方法,Object類的equals方法的實現代碼如下:
boolean equals(Object o){
return this==o;
}
這說明,如果一個類沒有自己定義equals方法,它預設的equals方法(從Object 類繼承的)就是使用==操作符,也是在比較兩個變數指向的對象是否是同一對象,這時候使用equals和使用==會得到同樣的結果,如果比較的是兩個獨立的對象則總返回false。如果你編寫的類希望能夠比較該類建立的兩個執行個體對象的內容是否相同,那麼你必須覆蓋equals方法,由你自己寫代碼來決定在什麼情況即可認為兩個對象的內容是相同的。
最後我個人認為還有一個大家很容易疏忽的內容是:靜態變數和執行個體變數的區別
在文法定義上的區別:靜態變數前要加static關鍵字,而執行個體變數前則不加。
在程式運行時的區別:執行個體變數屬於某個對象的屬性,必須建立了執行個體對象,其中的執行個體變數才會被分配空間,才能使用這個執行個體變數。靜態變數不屬於某個執行個體對象,而是屬於類,所以也稱為類變數,只要程式載入了類的位元組碼,不用建立任何執行個體對象,靜態變數就會被分配空間,靜態變數就可以被使用了。總之,執行個體變數必須建立對象後才可以通過這個對象來使用,靜態變數則可以直接使用類名來引用。
例如,對於下面的程式,無論建立多少個執行個體對象,永遠都只分配了一個staticVar變數,並且每建立一個執行個體對象,這個staticVar就會加1;但是,每建立一個執行個體對象,就會分配一個instanceVar,即可能分配多個instanceVar,並且每個instanceVar的值都只自加了1次。
public class VariantTest
{
public static int staticVar = 0;
public int instanceVar = 0;
public VariantTest()
{
staticVar++;
instanceVar++;
System.out.println(“staticVar=” + staticVar + ”,instanceVar=” + instanceVar);
}
平時易疏忽的java基礎知識