當前位置:才華齋>計算機>java語言>

Java常見誤區與細節有哪些呢

java語言 閱讀(1.3W)

Java的常見誤區與細節有哪些呢?看了下面的內容相信你就會清楚了。更多內容請關注應屆畢業生考試網!

Java常見誤區與細節有哪些呢
  一Java語言基礎中的誤區

1 在Java中,沒有 goto語句。因為大量使用 goto語句會降低程式的可讀性和可維護性,所以Java語言取消了 goto的使用。同時,為了避免程式設計師自行使用 goto所帶來的混亂,Java語言仍將 goto定義為一個關鍵字,但是沒有定義任何語法,故稱為“保留字”。

2 true、 false和 null在IDE中雖然以不同的顏色顯示了, 但是並不是關鍵字,而是“字面常量”,就和 String型別的 abc一樣。

3 定義名稱時儘量避免使用 $,因為 編譯器在對檔案進行編譯的時候,會將”$”編譯成頂層型別與底層型別的連線符。 見下例:

  使用$定義變數名

package ;

public class Outer$Inner {

public static void main(String[] args) {

Outer o = new Outer();

r i = Inner();

rPrint();

}

}

class Outer {

class Inner {

void innerPrint() {

tln("Inner Print!");

}

}

}

在編譯( javac )這段程式碼的時候,編譯器會報以下錯誤: : 錯誤: 類重複: r class Inner{ ^

  4 Unicode轉義字元處理的非常早,在解析程式之前。 例如:

Unicode編譯錯誤

// char c1 = 'u00a';

// char c2 = 'u00d';

在程式中出現這兩行程式碼編譯報錯。這兩個Unicode碼分別表示”換行”和”回車”,所以,在編譯器編譯的時候,程式碼是這樣的:

Unicode編譯

// char c1 = '

';

// char c2 = '

';

  5 Unicode碼使用16位字元編碼,在Java中用 char型別來表示。現在Unicode已經擴充套件到一百萬個字元,超出16位限制的成為增補字元。 所有增補字元都不能用字元常量來表示。

  6 當 short, byte, char參加運算時,結果為 int型,而非與較高的型別相同。

如果變數是 byte, short, byte型別,當對其賦予編譯時期的常量,而該常量又沒有超過變數的取值範圍時,,編譯器就可以進行隱式的收縮轉換。這種隱式的收縮轉換是安全的,因為該收縮轉換隻適用於變數的賦值,而不適用於方法呼叫語句,即不適用於方法呼叫時的引數傳遞。

7 注意 char型別,這是一個無符號型別。因此, char與 short或 char與 byte之間的轉換必須顯示地使用型別轉換。 從 byte到 char的轉換為擴充套件收縮轉換,該轉換比較特殊,即先將 byte擴充套件轉換到 int,然後再收縮到 char。

8 在整型資料間的擴充套件轉換中,如果運算元事 char型別(無符號型別),則進行無符號擴充套件,擴充套件位為0.如果運算元是 byte, short或 int(有符號型別),則進行有符號擴充套件,擴充套件位為該變數的符號位。

9 整型資料之間的收縮轉換,僅僅是截斷並丟棄高位,不做任何其他處理。 1 0.1+0.2不等於tln((double)0.1+(double)0.2);這條語句的輸出結果是 / / 0.30000000000000004。因為計算機使用二進位制來儲存資料,而很多小數都不能夠準確地使用二進位制來表示(事實上,大多數地小數都是近似的),就像使用十進位制小數不能準確地表示1/3這樣地分數一樣。大多數地浮點型,在計算機中只是近似地儲存其值,而不像整型那樣準確地儲存。又例,這是一個死迴圈: for(float f = 10.1f;f != 11;f+=0.1f){}

10 float型別可以保留7~8個有效數字,而 double型別可以保留15~16個有效數字,因而當 int型別或long型別數值多於 double或 float地有效數字時,該值的一些最低有效位就會丟失,從而造成精度丟失,這時,就會採用IEEE754最近舍入模式,提取與該整型值最接近的浮點值。 儘管整型向浮點型的轉換屬於擴充套件轉換,但當數值很大或很小(絕對值很大)時,就會產生一定的精度丟失。

11 i+++j如何計算?(這個問題在C/C++)中討論是沒有多大意義的,因為C/C++依賴於實現的硬體結構,不同的環境結果也會不同。不過在Java中,這個結果是固定的,不受其執行的硬體環境與平臺的影響) 答:根據貪心規則,前置++優於後置++,結果是 (i++)+j

12 i++和++i其實都是先+1,再賦值。++i,沒什麼好說的;i++,以 j=i++;為例在底層的實現是: temp = i;i = i + 1; j = temp; 所以, i=15;i=i++;這個表示式的結果是15.(因為加一之後又執行了一次賦值,從16變回15)

13 +0與-0在浮點型別變數儲存中,符號位是不同的。當-0和+0參與浮點型別的相關運算(例如相除與求餘運算)時,可以產生不同的結果。

14 浮點的相除與求餘運算不同與整型的相除與求餘運算,當除數為0時,浮點運算不會產生 ArithmeticException異常。

  二、Java面向物件中的誤區

15 String類是非可變類,其物件一旦建立,就不可銷燬。 String類那些看似修改字元序列的方法實際上都是返回新建立的 String物件,而不是修改自身物件。

16 由於 String物件是不可改變的,因此具有執行緒安全性,可以自由地實現共享。

17 在 String類內部,是使用一個字元陣列( char[])來維護字元序列的。 String的最大長度也就是字元陣列的最大長度,理論上最大長度為int型別的最大值,即2147483647.在實際中,一般可獲取的最大值小於理論最大值。

18 main()方法在表現行為上,與其他方法基本相同,可以過載,由其他方法呼叫,繼承,隱藏,也可以丟擲異常,帶有型別引數。我們也可以在一個程式中通過反射來呼叫 main方法 (或其他方法)。 2當兩個或多個方法的名稱相同,而引數列表不同時,這幾個方法就構成了過載。過載方法可以根據引數列表對應的型別與引數的個數來區分,但是,引數的名稱、方法的返回型別,方法的異常列表與型別引數不能作為區分過載方法的'條件。

19 究竟選擇哪個方法呼叫,順序是這樣的:

在第一階段,自動裝箱(拆箱)與可變引數不予考慮,搜尋對應形參型別可以匹配實參型別並且形參個數與實參個數相同的方法;

如果在步驟一不存在符合條件的方法,在第二階段,自動裝箱與拆箱將會執行。

如果在步驟二中不存在符合條件的方法,在第三階段,可變引數的方法將會考慮。

如果3個階段都沒有搜尋到符合條件的方法,將會產生編譯錯誤。如果如何條件的方法多於一個,將會選擇最明確的方法。最明確的方法定義為:如果A方法的形參列表型別對應的都可以賦值給B方法的形參列表型別,則A方法比B方法明確。如果無法選出最明確的方法,則會產生編譯錯誤。

20 重寫和隱藏的本質區別是:重寫是動態繫結的,根據執行時引用所指向物件的實際型別來決定呼叫相關類的成員。而隱藏是靜態繫結的,根據編譯時引用的靜態型別來決定呼叫的相關成員。換句話說,如果子類重寫了父類的方法,當父類的引用指向子類物件時,通過父類的引用呼叫的是子類方法。如果子類隱藏了父類的方法(成員變數),通過父類的引用呼叫的仍是父類的方法(成員變數)。

21 構造器是遞迴呼叫的,子類的構造器會呼叫父類的構造器,直到呼叫Object類的構造器為止。

22 構造器沒有建立物件,構造器是使用new建立物件時由系統呼叫的,用來初始化類的例項成員。從順序上說,先是建立物件,然後再呼叫構造器的。 (構造器並沒有產生新的物件)

23 預設的構造器不為空,該構造器會呼叫父類的無參構造器,並可能執行例項成員變數的初始化。所以,預設的構造器至少呼叫了父類的構造器,它做的工作還可能更多,包括例項變數宣告初始化與例項初始化塊,都是在構造器中執行的。

24 當==或!=運算子的兩個運算元的型別一個是基本資料型別,另一個是包裝類引用型別時,將引用型別拆箱轉換為基本資料型別,然後比較兩個基本資料型別的值是否相等。

25 在Java中,陣列也是類,陣列宣告的引用變數指向陣列型別的物件。所有的陣列都繼承 Object類,並且實現了 eable與 alizable介面。陣列的成員包括變數 length(隱式存在)與從Object類繼承的成員。 Cloneable與 Serializable是兩個標記的介面,這兩個介面中沒有顯式宣告任何成員。

  三、Java介面中的誤區

26 介面是完全抽象的設計,不能例項化。使A用 new方式建立的藉口型別,實際上是建立了一個匿名類,該匿名類實現了介面型別。

27 如果兩個介面聲明瞭相同的變數x,則當某介面同時繼承這兩個介面,或者某類同時實現這兩個介面時,通過簡單名稱訪問會產生編譯錯誤。

28 如果兩個介面中聲明瞭相同名稱的方法m,並且兩個方法沒有構成過載,則當某介面能夠同時繼承這兩個介面,或者某類能夠同時繼承這兩個介面時,必須存在一種方法簽名,使得該簽名同時為兩個m方法簽名的子簽名,並且在方法的返回型別上,必須存在一種型別,使得該型別同時為兩個m方法返回型別的可替換型別。