本文並沒有什麼新鮮的。我只是收集了一些不太重要的Java語句,但這些語句可能對初級程序員來說很重要。也就是些無聊的舊東西。
如果以下的這些你都知道的話,那麼你比Java的了解已經超過了對一個平常的家庭主婦的了解。我不知道清楚所有的這些是否是有意義的。即使不知道其中的一些特性,你照樣也可以成為一個相當不錯的Java程序員。然而,本文中許多的新信息可能表明你還有很大的發展空間。
這四種類型包括:private, package private (包訪問權限,無修飾符,又叫default, 譯者注)。如果你在類中定義一個元素時並不加任何訪問類型修飾符,它將被默認設置為包訪問權限(package private),而不是public或者protected。
Java有四個級別的訪問類型。
從另一方面來說,如果在接口中,你不指定方法的訪問修飾符,那麼它將是public類型的。你也可以顯式地指定它為public類型, 但這並不符合SONAR(一個開源代碼質量管理平台,譯者注)的代碼質量管理思想。
訪問類型是傳遞的
我的“在Java中允許選擇性的在接口的方法中寫public”的觀點是一個技術錯誤。
同樣你也可在接口的字段前寫final,甚至是static。這說明這些字段可以是非靜態或非final嗎?不是的,接口中的字段中總是final和static的。
Package private(或者default)訪問類型可以使得相同包(package)下其他類能夠訪問這些字段或方法。保護類型(protected)的方法和字段可以被相同包下的類使用(這和package private是一樣的),同時它也可以被其他類使用,只要那個類繼承了這個包含這些protected方法或字段的類。
如果有三個包a、b、c,每個包都分別包含A、B、C類,而且B繼承A,C繼承B,那麼C可以訪問A中的protected字段和方法。
很多人認為可以在接口中定義protected方法。如果你這麼做的話,編譯器很快就會毫不留情地給你報錯。順便說下,這也就是我為什麼認為允許public關鍵字在接口中是一個技術錯誤,它會讓人覺得還可以寫其他訪問類型似的。
private是一種新的public
如果你還想在一個接口的方法中聲明protected方法,你可能還不理解封裝的含義。
私有變量和方法在編譯單元內是可見的。如果這聽起來太神秘的話,換種說法:幾乎就是在同一個Java文件中。這比“在它們被定義的類中”聽起來好理解些。它們在同一編譯單元的類和接口中也是可見的。嵌套類可以看到類中封裝的私有字段和方法。然而,當前封閉類也可以看到該類下任何深度下類中的私有方法和字段。
後者並不廣為人知,事實上也很少有用到。
如果你可以訪問一個變量或方法,那麼不管它屬於哪個對象你都可以訪問它。如果this.a可以訪問到,那another.a也可以訪問到,只要它們是同一個類的實例。同一個類的實例對象可以隨意調用其他實例的變量或方法。不過這樣的代碼一般都沒有意義。現實生活中異常是equals()(由Eclipse生成, 15 - 18行):
訪問類型不是對象級別的而是類級別的。
那些不支持有任何實例的類,通常被稱為實用工具類。它們只包含靜態字段和靜態方法以及唯一的不被該類的任何靜態方法調用的私有構造函數。在Java 8中也可以有這樣的一個野獸(這個詞翻譯不通,譯者注)在接口中實現,因為Java 8的接口可以有靜態方法。我不覺得我們應該使用這個特性而不是實用工具類。我也不完全確信我��應該使用實用工具類。
靜態類總是在另一個類或接口中。它們是嵌套類。他們是靜態的,就像靜態方法不能訪問類的實例方法和字段一樣,靜態內部類也不能訪問嵌入類的實例方法和字段。這是因為內部類沒有嵌入類實例的引用(或者說是指針,如果你喜歡這麼叫的話)。內部類(內部類,也即非靜態嵌套類, 譯者注),而非靜態嵌套類, 沒有嵌入類的一個實例,它是無法被創建的。每個內部類的實例都具有嵌入類實例的一個引用,因此一個內部類可以訪問嵌入類的實例方法和字段。
因為這個原因,要是沒有外部類的一個實例,你就不能創建一個內部類。當然,如果是當前對象,也就是this的話,你就可以不需要指定它。在這種情況下你可以使用new, 在這種情況下,也就是this.new的簡式。在一個靜態的環境中,例如從一個靜態方法,你必須指定內部類應該創建哪個封閉類的實例。見第10行:
變量必須是有效的final
當一個匿名類被定義在一個方法中,它可以訪問局部變量如果該變量是final的。但這說的有點模糊。它們不得不聲明成final,他們還必須是有效final。這也是Java 8中發布的一些特性。你不需要聲明這些變量為final型,但它們仍然必須是有效的final。
Java 8並不要求final,只要求有效final。
為什麼你需要對一些東西聲明final,當它被檢查必須是這樣的。就像方法的參數。它們也必須是final的。你說這不是Java所必須的嗎?嗯,你是對的。這只是一個良好的編程風格所必須的。