欢迎使用Java 8之前要重温的10个JDK 7功能
Java 8發布已經快一個月了,我敢肯定,大家都在探索JDK 8的新功能。但是,在您完全研究Java 8之前,是時候重新審視Java 7上引入的一些很棒的功能了。記住,Java 6并沒有什么功能,它只與JVM的更改和性能有關,但是JDK 7確實引入了一些很酷的功能,這些功能改善了開發人員的日常任務。 為什么我現在要寫這篇文章? 為什么我在談論Java 1. 7,而每個人都在談論Java 8? 好吧,我認為,并非所有Java開發人員都熟悉JDK 7中引入的更改,并且與歡迎新版本相比,什么時候可以重新訪問早期版本。 我什至沒有看到開發人員在日常生活中使用自動資源管理 ,即使IDE已經為此提供了內容幫助。 盡管我看到程序員在Switch和Diamond運算符中使用String進行類型推斷,但是對于fork join框架 ,在一個catch塊中捕獲多個異常或在數字文字上使用下劃線的了解還是很少。 因此,我借此機會撰寫了一些總結性的文章,以修改這些方便的更改并將其應用到日常編程生活中。 在NIO和新的File API上有一些不錯的更改,在API級別上還有很多其他更改,這也值得一看。 我敢肯定,結合Java 8 lambda表達式 ,這些功能將導致更好更好的代碼。
在JDK 1.7之前引入了新的運算符<<,即菱形運算符,以使類型推斷也可用于構造函數。 在Java 7之前,類型推斷僅適用于方法,并且Joshua Bloch在有效Java 2nd Edition中正確地進行了預測,現在它也適用于構造函數 。 在JDK 7之前的版本中,您可以在對象創建表達式的左側和右側輸入更多類型,以指定類型,但是現在只需在左側創建類型,如下面的示例所示。
先前的JDK 7
Map<String, List<String>> employeeRecords = new HashMap<String, List<String>>(); List<Integer> primes = new ArrayList<Integer>();在JDK 7中
Map<String, List<String>> employeeRecords = new HashMap<>(); List<Integer> primes = new ArrayList<>();因此,在使用Collections(我們大量使用Generics)時 ,您不必在Java 7中鍵入更多內容。 有關Java中Diamond運算符的更多詳細信息,請參見此處。
在JDK 7之前,只能將整數類型用作switch-case語句的選擇器。 在JDK 7中,可以將String對象用作選擇器。 例如,
String state = "NEW";switch (day) {case "NEW": System.out.println("Order is in NEW state"); break;case "CANCELED": System.out.println("Order is Cancelled"); break;case "REPLACE": System.out.println("Order is replaced successfully"); break;case "FILLED": System.out.println("Order is filled"); break;default: System.out.println("Invalid");}比較時使用java.lang.String中的equals()和hashcode()方法,該方法區分大小寫。 在switch中使用String的好處是,與使用嵌套的if-then-else語句相比,Java編譯器可以生成更有效的代碼。 有關如何在Switch case語句中使用String的更多詳細信息,請參見此處。
在JDK 7之前,我們需要使用finally塊來確保關閉資源,而不管try語句是正常完成還是突然完成,例如,在讀取文件和流時,我們需要將它們關閉到finally塊中,從而導致很多樣板和混亂的代碼,如下所示:
public static void main(String args[]) {FileInputStream fin = null;BufferedReader br = null;try {fin = new FileInputStream("info.xml");br = new BufferedReader(new InputStreamReader(fin));if (br.ready()) {String line1 = br.readLine();System.out.println(line1);}} catch (FileNotFoundException ex) {System.out.println("Info.xml is not found");} catch (IOException ex) {System.out.println("Can't read the file");} finally {try {if (fin != null) fin.close();if (br != null) br.close();} catch (IOException ie) {System.out.println("Failed to close files");}}}看這段代碼,鍋爐代碼多少行?
現在在Java 7中,您可以使用try-with-resource功能自動關閉資源,該功能實現了AutoClosable和Closeable接口,例如Streams,Files,Socket句柄,數據庫連接等。JDK7引入了try-with-resources語句,該語句可確保通過調用AutoClosable的close()方法在語句末尾關閉try(resources)中的每個資源。 現在,Java 7中的相同示例如下所示,這是一個簡潔明了的代碼:
public static void main(String args[]) {try (FileInputStream fin = new FileInputStream("info.xml");BufferedReader br = new BufferedReader(new InputStreamReader(fin));) {if (br.ready()) {String line1 = br.readLine();System.out.println(line1);}} catch (FileNotFoundException ex) {System.out.println("Info.xml is not found");} catch (IOException ex) {System.out.println("Can't read the file");} }由于Java負責關閉包括文件和流在內的打開的資源,因此可能不再泄漏文件描述符,并且可能結束了文件描述符錯誤。 甚至JDBC 4.1也被改裝為AutoClosable。
fork / join框架是ExecutorService接口的實現,該接口使您可以利用現代服務器中可用的多個處理器。 它是為可以遞歸分解為較小部分的工作而設計的。 目標是使用所有可用的處理能力來增強應用程序的性能。 與任何ExecutorService實現一樣,fork / join框架將任務分配給線程池中的工作線程。 分支聯接框架與眾不同,因為它使用了一種工作竊取算法,該算法與生產者消費者算法有很大不同。 工作用盡的工作線程可以從其他仍很忙的線程中竊取任務。 fork / join框架的中心是ForkJoinPool類,它是AbstractExecutorService類的擴展。 ForkJoinPool實現了核心的工作竊取算法,并且可以執行ForkJoinTask進程。 您可以將代碼包裝在ForkJoinTask子類中,例如RecursiveTask(可以返回結果)或RecursiveAction。 有關Java中的fork聯接框架的更多信息,請參見此處 。
在JDK 7中,可以在數字文字(整數和浮點文字)的數字之間插入下劃線'_',以提高可讀性。 對于在源文件中使用大量數據的人而言,這尤其有價值,在金融和計算領域中可能很有用。 例如,
int billion = 1_000_000_000; // 10^9 long creditCardNumber = 1234_4567_8901_2345L; //16 digit number long ssn = 777_99_8888L; double pi = 3.1415_9265; float pif = 3.14_15_92_65f;您可以在下劃線處添加下劃線以使其更具可讀性,例如,大筆金額時,請在三位數之間加下劃線;對于信用卡號(長度為16位),在下劃線時請在第4位之后加下劃線在卡片上。 順便說一句,切記不能在下劃線數字之后,數字開頭或結尾處加下劃線。 例如,以下數字文字是無效的,因為下劃線的位置錯誤:
double pi = 3._1415_9265; // underscore just after decimal point long creditcardNum = 1234_4567_8901_2345_L; //underscore at the end of number long ssn = _777_99_8888L; //undersocre at the beginning有關更多信息和用例,請參閱我的文章有關如何在數字文字上使用下劃線 。
在JDK 7中,單個catch塊可以處理多個異常類型。
例如,在JDK 7之前,您需要兩個catch塊來捕獲兩種異常類型,盡管它們都執行相同的任務:
try {......} catch(ClassNotFoundException ex) {ex.printStackTrace(); } catch(SQLException ex) {ex.printStackTrace(); }在JDK 7中,您可以使用一個單獨的catch塊,其異常類型之間用'|'分隔。
try {......} catch(ClassNotFoundException|SQLException ex) {ex.printStackTrace();}順便說一句,請記住, 多重捕獲語句中的Alternatives不能通過子類關聯。 例如,如下所示的多捕獲語句將拋出編譯時錯誤:
try {......} catch (FileNotFoundException | IOException ex) {ex.printStackTrace();}Multi-catch語句中的替代項不能通過子類關聯,它會在編譯時引發錯誤:java.io.FileNotFoundException是Test.main(Test.java:18)的替代java.io.IOException的子類。
請參閱此處以了解有關Java SE 7中改進的異常處理的更多信息。
在JDK 7中,類似于C / C ++語言,您可以使用整數類型(字節,短型,整型和長型)的前綴“ 0b”(或“ 0B”)以二進制形式表示文字值。 在JDK 7之前,您只能使用八進制值(帶有前綴“ 0”)或十六進制值(帶有前綴“ 0x”或“ 0X”)。
int mask = 0b01010000101;甚至更好
int binary = 0B0101_0000_1010_0010_1101_0000_1010_0010;Java SE 7引入了java.nio.file軟件包及其相關軟件包java.nio.file.attribute,為文件I / O和訪問默認文件系統提供了全面的支持。 它還引入了Path類,該類允許您表示操作系統中的任何路徑。 新的文件系統API是對較早版本的補充,并提供了幾種有用的方法檢查,刪除,復制和移動文件。 例如,現在您可以檢查Java中是否隱藏了文件 。 您還可以從Java代碼創建符號鏈接和硬鏈接。 JDK 7新文件API還能夠使用通配符搜索文件。 您還將獲得支持以查看目錄中的更改。 我建議檢查新文件包的Java文檔,以了解有關此有趣的有用功能的更多信息。
JDK 7引入了一個稱為G1 Garbage Collection的新垃圾收集器,它是垃圾的縮寫形式。 G1垃圾收集器在垃圾最多的地方執行清理。 為了實現此目的,它將Java堆內存分為多個區域,而不是Java 7版本之前的3個區域(新,舊和永久性空間)。 據說G1完全可以預測,并且可以為內存密集型應用程序提供更高的吞吐量。
與早期版本的Java SE相比,Java SE 7編譯器對重新拋出的異常執行更精確的分析。 這使您可以在方法聲明的throws子句中指定更特定的異常類型。 在JDK 7之前,重新拋出異常被視為拋出catch參數的類型。 例如,如果您的try塊可以引發ParseException和IOException。 為了捕獲所有異常并重新拋出它們,您將必須捕獲Exception并將您的方法聲明為拋出Exception。 這是一種模糊的非精確拋出,因為您正在拋出常規的Exception類型(而不是特定的Exception類型),并且調用您的方法的語句需要捕獲此常規的Exception。 通過查看以下Java 1.7之前代碼中的異常處理示例,可以更清楚地了解這一點
public void obscure() throws Exception{try {new FileInputStream("abc.txt").read();new SimpleDateFormat("ddMMyyyy").parse("12-03-2014"); } catch (Exception ex) {System.out.println("Caught exception: " + ex.getMessage());throw ex;} }從JDK 7開始,可以在任何方法的throws子句中聲明Exception的類型時更加精確。 從以下事實確定拋出哪個異常的精度是:如果從catch塊重新拋出異常,則實際上是在拋出以下異常類型:
這樣可以改進對重新拋出的異常的檢查。 您可以更精確地了解從方法拋出的異常,并且可以在客戶端更好地處理它們,如以下示例所示:
public void precise() throws ParseException, IOException {try {new FileInputStream("abc.txt").read();new SimpleDateFormat("ddMMyyyy").parse("12-03-2014"); } catch (Exception ex) {System.out.println("Caught exception: " + ex.getMessage());throw ex;} }Java SE 7編譯器允許您在preciese()方法聲明中的throws子句中指定異常類型ParseException和IOException,因為您可以重新拋出一個異常,該異常是throws中聲明的任何類型的超類型,我們將拋出java.lang.Exception,它是所有選中的Exception的超類。 同樣在某些地方,您將看到帶有catch參數的final關鍵字,但這不再是必需的。
這就是您可以在JDK 7中進行修改的全部內容。Java 7的所有這些新功能對于實現干凈的代碼和提高開發人員的生產率非常有用。 隨著Java 8中引入的lambda表達式,這一實現Java中更干凈代碼的目標已達到另一個里程碑。 讓我知道,如果您認為我遺漏了Java 1.7的任何有用功能,那么您認為應該在這里。
PS:如果您喜歡書籍,那么您可能也喜歡Packet Publishing的Java 7 New features Cookbook。
翻譯自: https://www.javacodegeeks.com/2014/04/10-jdk-7-features-to-revisit-before-you-welcome-java-8.html
總結
以上是生活随笔為你收集整理的欢迎使用Java 8之前要重温的10个JDK 7功能的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 请问如何区别路由器和交换机如何区分交换机
- 下一篇: 使用ReentrantLock和Lamb
