'一個 Python 程序員的自述:我其實一直在用Java工作!文末附乾貨'
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
Most JS/Python/Ruby apps… http://pic.twitter.com/hkDkjdxpFH
— Reuben Bond (@reubenbond)
Java 卻有著對多線程和並行的一流支持。對於Java 1.7, 許並行的immutable數據結構令你輕鬆地在線程間共享數據。Akka庫更進一步的提供了Erlang型的Actors來寫併發和分佈式的程序。我並不是在說Java比Go具有更好的並行支持,但是可以管理單個線程這一特性為Java應用提供了異步性能;而Python是做不到這點的。
用最新的Java來編程
現在你的心情可能已經從噁心變成好奇了,那麼我們在2015年該如何寫Java呢?從哪兒開始呢?首先,讓我們回顧一些在Java 7和Java 8湧現的核心語言概念。
迭代
首先我們一起來看看迭代。下面是Java 8中的 for循環:
List<String> names = new LinkedList<>(); // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
或者是被大大簡化的 for關鍵詞?
for (String name : names)
System.out.println(name);
這2種循環結構都比你平時看到的for循環簡潔的多。
Lambda函數
上面提到的第一個for循環引入了Lambda函數這個新概念。Lamda函數,語法記作->, 是Java語言的一項重大改革,並從函數式編程中引入了一些概念。
下面來看幾個Java中Lambda函數的例子。
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Lambda Sorting
Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()))
// Lambda Listener
testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
這裡無法詳細展開Lambda函數這個話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個很好的切入點來更多地瞭解Lambda函數。
流:
Java 8引入了流(stream)的概念,這為Java提供了很多現代函數式語言的特性。流是一種對集合上的一系列轉換延遲執行的機制。比如我們來數一下以’A’開頭的名字。首先想到的方法肯定是像下面這樣:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names) {
if (name.startsWith("A"))
++count;
}
如果用流,上述就可以簡化為首先將集合轉換成流,然後使用函數:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
Java同時支持用parallelStream()來進行流的並行處理。並行流允許流水線業務在獨立的線程同時執行,這不僅改進了語法,同時提高了性能。在大多數情況下,你可以簡單得用parallelStream()替換stream()實現並行。
Try-With-Resources結構
在Java 6之前,打開一個文件然後讀取內容需要通過try/finally來完成:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實上並不知道readLine執行失敗。
Java 7引入了 Try-With-Resources結構來克服這種缺陷:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
上例中,無論在何種失敗情況下,BufferedReader都會自動關閉文件流。你可以通過用逗號分隔的方式,用一個try語句來打開多個資源。
多重catch
以往Java只允許一個catch代碼塊對應一個異常,這造成如下的代碼冗餘:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
從Java 7開始,你可以在一個代碼塊內捕捉多個異常,從而減少了代碼冗餘:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
數值字面常量(Numeric Literals)
數值字面常量可以添加下劃線是Java語言的新特性。這允許你使用_作為大數字的視覺分隔符。下面的例子不言自明:
int thousand = 1_000;
int million = 1_000_000;
使用Java
看到現代Java的語法如何簡化並擴展了老Java之後,你可能已經摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫,這些可以用來幫助你們上手。
結論
Java擁有一個漫長而傳奇的歷史,其中有好有壞。如果你已經很多年沒有使用Java工作了,也許現在是一個好機會再次嘗試它。只要不是像下面這樣做:
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
Most JS/Python/Ruby apps… http://pic.twitter.com/hkDkjdxpFH
— Reuben Bond (@reubenbond)
Java 卻有著對多線程和並行的一流支持。對於Java 1.7, 許並行的immutable數據結構令你輕鬆地在線程間共享數據。Akka庫更進一步的提供了Erlang型的Actors來寫併發和分佈式的程序。我並不是在說Java比Go具有更好的並行支持,但是可以管理單個線程這一特性為Java應用提供了異步性能;而Python是做不到這點的。
用最新的Java來編程
現在你的心情可能已經從噁心變成好奇了,那麼我們在2015年該如何寫Java呢?從哪兒開始呢?首先,讓我們回顧一些在Java 7和Java 8湧現的核心語言概念。
迭代
首先我們一起來看看迭代。下面是Java 8中的 for循環:
List<String> names = new LinkedList<>(); // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
或者是被大大簡化的 for關鍵詞?
for (String name : names)
System.out.println(name);
這2種循環結構都比你平時看到的for循環簡潔的多。
Lambda函數
上面提到的第一個for循環引入了Lambda函數這個新概念。Lamda函數,語法記作->, 是Java語言的一項重大改革,並從函數式編程中引入了一些概念。
下面來看幾個Java中Lambda函數的例子。
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Lambda Sorting
Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()))
// Lambda Listener
testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
這裡無法詳細展開Lambda函數這個話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個很好的切入點來更多地瞭解Lambda函數。
流:
Java 8引入了流(stream)的概念,這為Java提供了很多現代函數式語言的特性。流是一種對集合上的一系列轉換延遲執行的機制。比如我們來數一下以’A’開頭的名字。首先想到的方法肯定是像下面這樣:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names) {
if (name.startsWith("A"))
++count;
}
如果用流,上述就可以簡化為首先將集合轉換成流,然後使用函數:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
Java同時支持用parallelStream()來進行流的並行處理。並行流允許流水線業務在獨立的線程同時執行,這不僅改進了語法,同時提高了性能。在大多數情況下,你可以簡單得用parallelStream()替換stream()實現並行。
Try-With-Resources結構
在Java 6之前,打開一個文件然後讀取內容需要通過try/finally來完成:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實上並不知道readLine執行失敗。
Java 7引入了 Try-With-Resources結構來克服這種缺陷:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
上例中,無論在何種失敗情況下,BufferedReader都會自動關閉文件流。你可以通過用逗號分隔的方式,用一個try語句來打開多個資源。
多重catch
以往Java只允許一個catch代碼塊對應一個異常,這造成如下的代碼冗餘:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
從Java 7開始,你可以在一個代碼塊內捕捉多個異常,從而減少了代碼冗餘:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
數值字面常量(Numeric Literals)
數值字面常量可以添加下劃線是Java語言的新特性。這允許你使用_作為大數字的視覺分隔符。下面的例子不言自明:
int thousand = 1_000;
int million = 1_000_000;
使用Java
看到現代Java的語法如何簡化並擴展了老Java之後,你可能已經摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫,這些可以用來幫助你們上手。
結論
Java擁有一個漫長而傳奇的歷史,其中有好有壞。如果你已經很多年沒有使用Java工作了,也許現在是一個好機會再次嘗試它。只要不是像下面這樣做:
最新Java教程獲取方式:轉發關注+私信菜菜關鍵詞 “ Java ”,即可免費獲取哦!
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
Most JS/Python/Ruby apps… http://pic.twitter.com/hkDkjdxpFH
— Reuben Bond (@reubenbond)
Java 卻有著對多線程和並行的一流支持。對於Java 1.7, 許並行的immutable數據結構令你輕鬆地在線程間共享數據。Akka庫更進一步的提供了Erlang型的Actors來寫併發和分佈式的程序。我並不是在說Java比Go具有更好的並行支持,但是可以管理單個線程這一特性為Java應用提供了異步性能;而Python是做不到這點的。
用最新的Java來編程
現在你的心情可能已經從噁心變成好奇了,那麼我們在2015年該如何寫Java呢?從哪兒開始呢?首先,讓我們回顧一些在Java 7和Java 8湧現的核心語言概念。
迭代
首先我們一起來看看迭代。下面是Java 8中的 for循環:
List<String> names = new LinkedList<>(); // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
或者是被大大簡化的 for關鍵詞?
for (String name : names)
System.out.println(name);
這2種循環結構都比你平時看到的for循環簡潔的多。
Lambda函數
上面提到的第一個for循環引入了Lambda函數這個新概念。Lamda函數,語法記作->, 是Java語言的一項重大改革,並從函數式編程中引入了一些概念。
下面來看幾個Java中Lambda函數的例子。
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Lambda Sorting
Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()))
// Lambda Listener
testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
這裡無法詳細展開Lambda函數這個話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個很好的切入點來更多地瞭解Lambda函數。
流:
Java 8引入了流(stream)的概念,這為Java提供了很多現代函數式語言的特性。流是一種對集合上的一系列轉換延遲執行的機制。比如我們來數一下以’A’開頭的名字。首先想到的方法肯定是像下面這樣:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names) {
if (name.startsWith("A"))
++count;
}
如果用流,上述就可以簡化為首先將集合轉換成流,然後使用函數:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
Java同時支持用parallelStream()來進行流的並行處理。並行流允許流水線業務在獨立的線程同時執行,這不僅改進了語法,同時提高了性能。在大多數情況下,你可以簡單得用parallelStream()替換stream()實現並行。
Try-With-Resources結構
在Java 6之前,打開一個文件然後讀取內容需要通過try/finally來完成:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實上並不知道readLine執行失敗。
Java 7引入了 Try-With-Resources結構來克服這種缺陷:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
上例中,無論在何種失敗情況下,BufferedReader都會自動關閉文件流。你可以通過用逗號分隔的方式,用一個try語句來打開多個資源。
多重catch
以往Java只允許一個catch代碼塊對應一個異常,這造成如下的代碼冗餘:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
從Java 7開始,你可以在一個代碼塊內捕捉多個異常,從而減少了代碼冗餘:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
數值字面常量(Numeric Literals)
數值字面常量可以添加下劃線是Java語言的新特性。這允許你使用_作為大數字的視覺分隔符。下面的例子不言自明:
int thousand = 1_000;
int million = 1_000_000;
使用Java
看到現代Java的語法如何簡化並擴展了老Java之後,你可能已經摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫,這些可以用來幫助你們上手。
結論
Java擁有一個漫長而傳奇的歷史,其中有好有壞。如果你已經很多年沒有使用Java工作了,也許現在是一個好機會再次嘗試它。只要不是像下面這樣做:
最新Java教程獲取方式:轉發關注+私信菜菜關鍵詞 “ Java ”,即可免費獲取哦!
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
Most JS/Python/Ruby apps… http://pic.twitter.com/hkDkjdxpFH
— Reuben Bond (@reubenbond)
Java 卻有著對多線程和並行的一流支持。對於Java 1.7, 許並行的immutable數據結構令你輕鬆地在線程間共享數據。Akka庫更進一步的提供了Erlang型的Actors來寫併發和分佈式的程序。我並不是在說Java比Go具有更好的並行支持,但是可以管理單個線程這一特性為Java應用提供了異步性能;而Python是做不到這點的。
用最新的Java來編程
現在你的心情可能已經從噁心變成好奇了,那麼我們在2015年該如何寫Java呢?從哪兒開始呢?首先,讓我們回顧一些在Java 7和Java 8湧現的核心語言概念。
迭代
首先我們一起來看看迭代。下面是Java 8中的 for循環:
List<String> names = new LinkedList<>(); // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
或者是被大大簡化的 for關鍵詞?
for (String name : names)
System.out.println(name);
這2種循環結構都比你平時看到的for循環簡潔的多。
Lambda函數
上面提到的第一個for循環引入了Lambda函數這個新概念。Lamda函數,語法記作->, 是Java語言的一項重大改革,並從函數式編程中引入了一些概念。
下面來看幾個Java中Lambda函數的例子。
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Lambda Sorting
Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()))
// Lambda Listener
testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
這裡無法詳細展開Lambda函數這個話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個很好的切入點來更多地瞭解Lambda函數。
流:
Java 8引入了流(stream)的概念,這為Java提供了很多現代函數式語言的特性。流是一種對集合上的一系列轉換延遲執行的機制。比如我們來數一下以’A’開頭的名字。首先想到的方法肯定是像下面這樣:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names) {
if (name.startsWith("A"))
++count;
}
如果用流,上述就可以簡化為首先將集合轉換成流,然後使用函數:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
Java同時支持用parallelStream()來進行流的並行處理。並行流允許流水線業務在獨立的線程同時執行,這不僅改進了語法,同時提高了性能。在大多數情況下,你可以簡單得用parallelStream()替換stream()實現並行。
Try-With-Resources結構
在Java 6之前,打開一個文件然後讀取內容需要通過try/finally來完成:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實上並不知道readLine執行失敗。
Java 7引入了 Try-With-Resources結構來克服這種缺陷:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
上例中,無論在何種失敗情況下,BufferedReader都會自動關閉文件流。你可以通過用逗號分隔的方式,用一個try語句來打開多個資源。
多重catch
以往Java只允許一個catch代碼塊對應一個異常,這造成如下的代碼冗餘:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
從Java 7開始,你可以在一個代碼塊內捕捉多個異常,從而減少了代碼冗餘:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
數值字面常量(Numeric Literals)
數值字面常量可以添加下劃線是Java語言的新特性。這允許你使用_作為大數字的視覺分隔符。下面的例子不言自明:
int thousand = 1_000;
int million = 1_000_000;
使用Java
看到現代Java的語法如何簡化並擴展了老Java之後,你可能已經摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫,這些可以用來幫助你們上手。
結論
Java擁有一個漫長而傳奇的歷史,其中有好有壞。如果你已經很多年沒有使用Java工作了,也許現在是一個好機會再次嘗試它。只要不是像下面這樣做:
最新Java教程獲取方式:轉發關注+私信菜菜關鍵詞 “ Java ”,即可免費獲取哦!
每當我告訴別人,大家的反應都是:“為啥是Java?”
說實話,本人剛開始的時候也是同樣的反應。但是由於Java的類型安全,執行性能和堅如磐石的工具,我漸漸地開始欣賞Java。同時我注意到,現在的Java已今非昔比 —— 它在過去的10年間穩健地改善著。
為何是Java?
假設每天都用Java的想法還沒有讓君噁心到食不下咽,我在此重申Java已非你所瞭解的“吳下阿蒙”了。當Python, Ruby, 和Javascript在“動態類型語言革命”™(我自己造的名詞)中大放異彩時,Java已經悄悄地借鑑了動態語言和函數式語言的很多吸引人的特性,同時保留了讓Java和JVM晉級一流開發環境的先賢的努力成果。憑藉大約9百萬Java攻城獅的基層群體,Java仍然是世界上最受歡迎的編程語言。我們不能僅僅因為Java的語法有一點點繁瑣,就抹殺掉它所有的歷史和開發工作。但是流行不等同於正確。下面我們就來看看是什麼讓Java如此大放異彩。
Java虛擬機(JVM)
Java虛擬機(JVM) 已經誕生20年了。在此期間,它被部署在成千上萬的系統上,歷經了無數的漏洞修復和性能提升。JVM的優點有以下幾個方面。首先,JVM完美支持日誌和監控,這使你可以很方便地監控小到單個線程的性能指標。JVM有世界上最優化的垃圾回收器之一,你可以根據優化吞吐量等因素靈活選擇垃圾回收算法。最後,Java承諾的“write once, run
anywhere”終於得已實現——你可以輕鬆地在任何架構上部署一個Java應用(大家還是承認applet從來沒有過吧)。為什麼用Scala和 Clojure這樣新式語言的聰明人會選擇JVM作為他們的執行環境呢?——因為JVM為你的代碼提供了一個無出其右的分發環境。拋棄像JVM這樣堅如磐石的工具是非常不合理的。
庫的支持
如果你需要做點什麼,很可能已經有非常好用且經過測試的Java庫在等著你。Java庫大部分都是成熟並用於實際生產開發的。Google, Amazon, LinkedIn, Twitter和很多Apache項目都很倚重於Java。如果你用了Java,你可以參考這些庫和公司,從而借鑑偉大的程序員先驅們的工作。
類型安全
Java的類型系統,雖然有時很繁瑣,但是這使得你可以寫出“好用”的代碼。不再有運行調試,它使你可以依靠編譯器而不是單元測試——單元測試只在你知道bug在哪裡的時候才有用。類型安全也使你輕鬆的代碼重構。Java同時支持範型——Go語言的最大詬病之一。再者,Guava這樣的庫I以最小的樣板和開銷,標準化了創建類型安全的API的方法。Java編譯器的改進也意味著你可以在享受類型安全的同時最小化範型所需的樣板代碼。
併發性
下面這條tweet總結了大多數動態語言的並行狀態:
Most JS/Python/Ruby apps… http://pic.twitter.com/hkDkjdxpFH
— Reuben Bond (@reubenbond)
Java 卻有著對多線程和並行的一流支持。對於Java 1.7, 許並行的immutable數據結構令你輕鬆地在線程間共享數據。Akka庫更進一步的提供了Erlang型的Actors來寫併發和分佈式的程序。我並不是在說Java比Go具有更好的並行支持,但是可以管理單個線程這一特性為Java應用提供了異步性能;而Python是做不到這點的。
用最新的Java來編程
現在你的心情可能已經從噁心變成好奇了,那麼我們在2015年該如何寫Java呢?從哪兒開始呢?首先,讓我們回顧一些在Java 7和Java 8湧現的核心語言概念。
迭代
首先我們一起來看看迭代。下面是Java 8中的 for循環:
List<String> names = new LinkedList<>(); // compiler determines type of LinkedList
// ... add some names to the collection
names.forEach(name -> System.out.println(name));
或者是被大大簡化的 for關鍵詞?
for (String name : names)
System.out.println(name);
這2種循環結構都比你平時看到的for循環簡潔的多。
Lambda函數
上面提到的第一個for循環引入了Lambda函數這個新概念。Lamda函數,語法記作->, 是Java語言的一項重大改革,並從函數式編程中引入了一些概念。
下面來看幾個Java中Lambda函數的例子。
// Lambda Runnable
Runnable r2 = () -> System.out.println("Hello world two!");
// Lambda Sorting
Collections.sort(personList, (Person p1, Person p2) -> p1.getSurName().compareTo(p2.getSurName()))
// Lambda Listener
testButton.addActionListener(e -> System.out.println("Click Detected by Lambda Listener"));
這裡無法詳細展開Lambda函數這個話題——http://www.drdobbs.com/jvm/lambda-expressions-in-java-8/240166764文章提供了一個很好的切入點來更多地瞭解Lambda函數。
流:
Java 8引入了流(stream)的概念,這為Java提供了很多現代函數式語言的特性。流是一種對集合上的一系列轉換延遲執行的機制。比如我們來數一下以’A’開頭的名字。首先想到的方法肯定是像下面這樣:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = 0;
for (String name : names) {
if (name.startsWith("A"))
++count;
}
如果用流,上述就可以簡化為首先將集合轉換成流,然後使用函數:
List<String> names = new LinkedList<>();
// ... add some names to the collection
long count = names.stream()
.filter(name -> name.startsWith("A"))
.count();
Java同時支持用parallelStream()來進行流的並行處理。並行流允許流水線業務在獨立的線程同時執行,這不僅改進了語法,同時提高了性能。在大多數情況下,你可以簡單得用parallelStream()替換stream()實現並行。
Try-With-Resources結構
在Java 6之前,打開一個文件然後讀取內容需要通過try/finally來完成:
static String readFirstLineFromFileWithFinallyBlock(String path)
throws IOException {
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
if (br != null) br.close();
}
}
但是readLine和close都有可能拋出異常。在這種情況下,readLine拋出的異常被忽略,我們事實上並不知道readLine執行失敗。
Java 7引入了 Try-With-Resources結構來克服這種缺陷:
static String readFirstLineFromFile(String path) throws IOException {
try (BufferedReader br =
new BufferedReader(new FileReader(path))) {
return br.readLine();
}
}
上例中,無論在何種失敗情況下,BufferedReader都會自動關閉文件流。你可以通過用逗號分隔的方式,用一個try語句來打開多個資源。
多重catch
以往Java只允許一個catch代碼塊對應一個異常,這造成如下的代碼冗餘:
catch (IOException ex) {
logger.log(ex);
throw ex;
catch (SQLException ex) {
logger.log(ex);
throw ex;
}
從Java 7開始,你可以在一個代碼塊內捕捉多個異常,從而減少了代碼冗餘:
catch (IOException|SQLException ex) {
logger.log(ex);
throw ex;
}
數值字面常量(Numeric Literals)
數值字面常量可以添加下劃線是Java語言的新特性。這允許你使用_作為大數字的視覺分隔符。下面的例子不言自明:
int thousand = 1_000;
int million = 1_000_000;
使用Java
看到現代Java的語法如何簡化並擴展了老Java之後,你可能已經摩拳擦掌躍躍欲試Java了。我整理了一下第三方的工具和庫,這些可以用來幫助你們上手。
結論
Java擁有一個漫長而傳奇的歷史,其中有好有壞。如果你已經很多年沒有使用Java工作了,也許現在是一個好機會再次嘗試它。只要不是像下面這樣做: