一、在Java中,沒有goto
語句。由於大量使用goto
語句會下降程序的可讀性和可維護性,因此Java語言取消了goto
的使用。同時,爲了不程序員自行使用goto
所帶來的混亂,Java語言仍將goto
定義爲一個關鍵字,可是沒有定義任何語法,故稱爲「保留字」。
java
2 true
、false
和null
在IDE中雖然以不一樣的顏色顯示,可是並非關鍵字,而是「字面常量」,就和String
類型的abc
同樣。程序員
3 定義名稱時儘可能避免使用$
,由於編譯器在對.java文件進行編譯的時候,會將」$」編譯成頂層類型與底層類型的鏈接符。見下例:數組
在編譯(javac Test3.java
)這段代碼的時候,編譯器會報如下錯誤:Test.java:12: 錯誤: 類重複: com.javastack.Test.Outer.Inner class Inner{ ^
安全
4 Unicode轉義字符處理的很是早,在解析程序以前。例如:微信
在程序中出現這兩行代碼編譯報錯。這兩個Unicode碼分別表示」換行」和」回車」,因此,在編譯器編譯的時候,代碼是這樣的:ide
5 Unicode碼使用16位字符編碼,在Java中用char
類型來表示。如今Unicode已經擴展到一百萬個字符,超出16位限制的成爲增補字符。全部增補字符都不能用字符常量來表示。編碼
6 當short
,byte
,char
參加運算時,結果爲int
型,而非與較高的類型相同。若是變量是byte
,short
,byte
類型,當對其賦予編譯時期的常量,而該常量又沒有超過變量的取值範圍時,編譯器就能夠進行隱式的收縮轉換。這種隱式的收縮轉換是安全的,由於該收縮轉換隻適用於變量的賦值,而不適用於方法調用語句,即不適用於方法調用時的參數傳遞。(詳見java中默認類型轉換的小問題)spa
7 注意char
類型,這是一個無符號類型。所以,char
與short
或char
與byte
之間的轉換必須顯示地使用類型轉換。 從byte
到char
的轉換爲擴展收縮轉換,該轉換比較特殊,即先將byte
擴輾轉換到int
,而後再收縮到char
。線程
8 在整型數據間的擴輾轉換中,若是操做數是char
類型(無符號類型),則進行無符號擴展,擴展位爲0.若是操做數是byte
,short
或int
(有符號類型),則進行有符號擴展,擴展位爲該變量的符號位。設計
9 整型數據之間的收縮轉換,僅僅是截斷並丟棄高位,不作任何其餘處理。
10 0.1+0.2不等於0.3.System.out.println((double)0.1+(double)0.2);
這條語句的輸出結果是0.30000000000000004
。由於計算機使用二進制來存儲數據,而不少小數都不可以準確地使用二進制來表示(事實上,大多數地小數都是近似的),就像使用十進制小數不能準確地表示1/3這樣地分數同樣。大多數地浮點型,在計算機中只是近似地存儲其值,而不像整型那樣準確地存儲。又例,這是一個死循環:for(float f = 10.1f;f != 11;f+=0.1f){}
11 float類型能夠保留7~8個有效數字,而double類型能夠保留15~16個有效數字,於是當int類型或long類型數值多於double或float地有效數字時,該值的一些最低有效位就會丟失,從而形成精度丟失,這時,就會採用IEEE754最近舍入模式,提取與該整型值最接近的浮點值。儘管整型向浮點型的轉換屬於擴輾轉換,但當數值很大或很小(絕對值很大)時,就會產生必定的精度丟失。
12 i+++j
如何計算?(這個問題在C/C++)中討論是沒有多大意義的,由於C/C++依賴於實現的硬件結構,不一樣的環境結果也會不一樣。不過在Java中,這個結果是固定的,不受其運行的硬件環境與平臺的影響) 答:根據貪心規則,前置++優於後置++,結果是(i++)+j
13 i++和++i其實都是先+1,再賦值。++i,沒什麼好說的;i++,以j=i++;
爲例在底層的實現是:temp = i;i = i + 1; j = temp;
因此,i=15;i=i++;
這個表達式的結果是15.(由於加一以後又執行了一次賦值,從16變回15)
14 +0與-0在浮點類型變量存儲中,符號位是不一樣的。當-0和+0參與浮點類型的相關運算(例如相除與求餘運算)時,能夠產生不一樣的結果。
15 浮點的相除與求餘運算不一樣與整型的相除與求餘運算,當除數爲0時,浮點運算不會產生ArithmeticException
異常。
16 String
類是非可變類,其對象一旦建立,就不可銷燬。String
類那些看似修改字符序列的方法實際上都是返回新建立的String
對象,而不是修改自身對象。
17 因爲String
對象是不可改變的,所以具備線程安全性,能夠自由地實現共享。
18 在String
類內部,是使用一個字符數組(char[]
)來維護字符序列的。String
的最大長度也就是字符數組的最大長度,理論上最大長度爲int類型的最大值,即2147483647.在實際中,通常可獲取的最大值小於理論最大值。
19 main()
方法在表現行爲上,與其餘方法基本相同,能夠重載,由其餘方法調用,繼承,隱藏,也能夠拋出異常,帶有類型參數。咱們也能夠在一個程序中經過反射來調用main方法
(或其餘方法)。
20 當兩個或多個方法的名稱相同,而參數列表不一樣時,這幾個方法就構成了重載。重載方法能夠根據參數列表對應的類型與參數的個數來區分,可是,參數的名稱、方法的返回類型,方法的異常列表與類型參數不能做爲區分重載方法的條件。
21 究竟選擇哪一個方法調用,順序是這樣的:
在第一階段,自動裝箱(拆箱)與可變參數不予考慮,搜索對應形參類型能夠匹配實參類型而且形參個數與實參個數相同的方法;
若是在步驟一不存在符合條件的方法,在第二階段,自動裝箱與拆箱將會執行。
若是在步驟二中不存在符合條件的方法,在第三階段,可變參數的方法將會考慮。
若是3個階段都沒有搜索到符合條件的方法,將會產生編譯錯誤。若是如何條件的方法多於一個,將會選擇最明確的方法。最明確的方法定義爲:若是A方法的形參列表類型對應的均可以賦值給B方法的形參列表類型,則A方法比B方法明確。若是沒法選出最明確的方法,則會產生編譯錯誤。
22 重寫和隱藏的本質區別是:重寫是動態綁定的,根據運行時引用所指向對象的實際類型來決定調用相關類的成員。而隱藏是靜態綁定的,根據編譯時引用的靜態類型來決定調用的相關成員。換句話說,若是子類重寫了父類的方法,當父類的引用指向子類對象時,經過父類的引用調用的是子類方法。若是子類隱藏了父類的方法(成員變量),經過父類的引用調用的還是父類的方法(成員變量)。
23 構造器是遞歸調用的,子類的構造器會調用父類的構造器,直到調用Object類的構造器爲止。
24 構造器沒有建立對象,構造器是使用new建立對象時由系統調用的,用來初始化類的實例成員。從順序上說,先是建立對象,而後再調用構造器的。(構造器並無產生新的對象)
25 默認的構造器不爲空,該構造器會調用父類的無參構造器,並可能執行實例成員變量的初始化。因此,默認的構造器至少調用了父類的構造器,它作的工做還可能更多,包括實例變量聲明初始化與實例初始化塊,都是在構造器中執行的。
26 當==或!=運算符的兩個操做數的類型一個是基本數據類型,另外一個是包裝類引用類型時,將引用類型拆箱轉換爲基本數據類型,而後比較兩個基本數據類型的值是否相等。
27 在Java中,數組也是類,數組聲明的引用變量指向數組類型的對象。全部的數組都繼承Object
類,而且實現了java.lang.Cloneable
與java.io.Serializable
接口。數組的成員包括變量length
(隱式存在)與從Object類繼承的成員。Cloneable
與Serializable
是兩個標記的接口,這兩個接口中沒有顯式聲明任何成員。
28 接口是徹底抽象的設計,不能實例化。使A用new
方式建立的藉口類型,其實是建立了一個匿名類,該匿名類實現了接口類型。
29 若是兩個接口聲明瞭相同的變量x,則當某接口同時繼承這兩個接口,或者某類同時實現這兩個接口時,經過簡單名稱訪問會產生編譯錯誤。
30 若是兩個接口中聲明瞭相同名稱的方法m,而且兩個方法沒有構成重載,則當某接口可以同時繼承這兩個接口,或者某類可以同時繼承這兩個接口時,必須存在一種方法簽名,使得該簽名同時爲兩個m方法簽名的子簽名,而且在方法的返回類型上,必須存在一種類型,使得該類型同時爲兩個m方法返回類型的可替換類型。
我有一個微信公衆號,常常會分享一些Java技術相關的乾貨;若是你喜歡個人分享,能夠用微信搜索「Java團長」或者「javatuanzhang」關注。