1. 程式人生 > >jdk7和8的一些新特性介紹

jdk7和8的一些新特性介紹

本文是我學習瞭解了jdk7和jdk8的一些新特性的一些資料,有興趣的大家可以瀏覽下下面的內容。  
  1. 官方文件:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html
  2. 在jdk7的新特性方面主要有下面幾方面的增強:  
  3. 1.jdk7語法上  
  4. 1.1二進位制變數的表示,支援將整數型別用二進位制來表示,用0b開頭。  
  5. // 所有整數 int, short,long,byte都可以用二進位制表示
  6. // An 8-bit 'byte' value:
  7. byte aByte = (byte) 0b00100001;  
  8. // A 16-bit 'short' value:
  9. short aShort = (short) 0b1010000101000101;  
  10. // Some 32-bit 'int' values:
  11.     intanInt1 = 0b10100001010001011010000101000101;  
  12.     intanInt2 = 0b101;  
  13.     intanInt3 = 0B101; // The B can be upper or lower case.
  14. // A 64-bit 'long' value. Note the "L" suffix:
  15. long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;  
  16. // 二進位制在陣列等的使用
  17. finalint[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001,  
  18.     0b00010011, 0b00100110, 0b01001100, 0b10011000 };  
  19. 1.2  Switch語句支援string型別   
  20. publicstatic String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {  
  21.          String typeOfDay;  
  22. switch (dayOfWeekArg) {  
  23. case"Monday":  
  24.                  typeOfDay = "Start of work week";  
  25. break;  
  26. case"Tuesday":  
  27. case"Wednesday":  
  28. case"Thursday"
    :  
  29.                  typeOfDay = "Midweek";  
  30. break;  
  31. case"Friday":  
  32.                  typeOfDay = "End of work week";  
  33. break;  
  34. case"Saturday":  
  35. case"Sunday":  
  36.                  typeOfDay = "Weekend";  
  37. break;  
  38. default:  
  39. thrownew IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);  
  40.          }  
  41. return typeOfDay;  
  42.     }   
  43. 1.3 Try-with-resource語句   
  44.   注意:實現java.lang.AutoCloseable介面的資源都可以放到try中,跟final裡面的關閉資源類似; 按照宣告逆序關閉資源 ;Try塊丟擲的異常通過Throwable.getSuppressed獲取   
  45. try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);  
  46.     java.io.BufferedWriter writer = java.nio.file.Files   
  47.     .newBufferedWriter(outputFilePath, charset)) {  
  48. // Enumerate each entry
  49. for (java.util.Enumeration entries = zf.entries(); entries  
  50.     .hasMoreElements();) {  
  51. // Get the entry name and write it to the output file
  52.     String newLine = System.getProperty("line.separator");  
  53.     String zipEntryName = ((java.util.zip.ZipEntry) entries  
  54.     .nextElement()).getName() + newLine;  
  55.     writer.write(zipEntryName, 0, zipEntryName.length());  
  56.     }  
  57.     }  
  58. 1.4 Catch多個異常 說明:Catch異常型別為final; 生成Bytecode 會比多個catch小; Rethrow時保持異常型別   
  59. publicstaticvoid main(String[] args) throws Exception {  
  60. try {  
  61.     testthrows();  
  62.     } catch (IOException | SQLException ex) {  
  63. throw ex;  
  64.     }  
  65.     }  
  66. publicstaticvoid testthrows() throws IOException, SQLException {  
  67.     }  
  68. 1.5 數字型別的下劃線表示 更友好的表示方式,不過要注意下劃線新增的一些標準,可以參考下面的示例  
  69. long creditCardNumber = 1234_5678_9012_3456L;  
  70. long socialSecurityNumber = 999_99_9999L;  
  71. float pi = 3.14_15F;  
  72. long hexBytes = 0xFF_EC_DE_5E;  
  73. long hexWords = 0xCAFE_BABE;  
  74. long maxLong = 0x7fff_ffff_ffff_ffffL;  
  75. byte nybbles = 0b0010_0101;  
  76. long bytes = 0b11010010_01101001_10010100_10010010;   
  77. //float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent to a decimal point
  78. //float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent to a decimal point
  79. //long socialSecurityNumber1= 999_99_9999_L;         // Invalid; cannot put underscores prior to an L suffix 
  80. //int x1 = _52;              // This is an identifier, not a numeric literal
  81. int x2 = 5_2;              // OK (decimal literal)
  82. //int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal
  83. int x4 = 5_______2;        // OK (decimal literal) 
  84. //int x5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix
  85. //int x6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number
  86. int x7 = 0x5_2;            // OK (hexadecimal literal)
  87. //int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number 
  88. int x9 = 0_52;             // OK (octal literal)
  89. int x10 = 05_2;            // OK (octal literal)
  90. //int x11 = 052_;            // Invalid; cannot put underscores at the end of a number 
  91. 1.6 泛型例項的建立可以通過型別推斷來簡化 可以去掉後面new部分的泛型型別,只用<>就可以了。  
  92. //使用泛型前 
  93.     List strList = new ArrayList();   
  94.     List<String> strList4 = new ArrayList<String>();   
  95.     List<Map<String, List<String>>> strList5 =  new ArrayList<Map<String, List<String>>>();  
  96. //編譯器使用尖括號 (<>) 推斷型別 
  97.     List<String> strList0 = new ArrayList<String>();   
  98.     List<Map<String, List<String>>> strList1 =  new ArrayList<Map<String, List<String>>>();   
  99.     List<String> strList2 = new ArrayList<>();   
  100.     List<Map<String, List<String>>> strList3 = new ArrayList<>();  
  101.     List<String> list = new ArrayList<>();  
  102.     list.add("A");  
  103. // The following statement should fail since addAll expects
  104. // Collection<? extends String>
  105. //list.addAll(new ArrayList<>()); 
  106. 1.7在可變引數方法中傳遞非具體化引數,改進編譯警告和錯誤   
  107. Heap pollution 指一個變數被指向另外一個不是相同型別的變數。例如  
  108.     List l = new ArrayList<Number>();  
  109.     List<String> ls = l;       // unchecked warning
  110.     l.add(0new Integer(42)); // another unchecked warning
  111.     String s = ls.get(0);      // ClassCastException is thrown
  112.     Jdk7:  
  113. publicstatic <T> void addToList (List<T> listArg, T... elements) {  
  114. for (T x : elements) {  
  115.     listArg.add(x);  
  116.     }  
  117.     }  
  118.     你會得到一個warning  
  119.     warning: [varargs] Possible heap pollution from parameterized vararg type  
  120.     要消除警告,可以有三種方式  
  121. 1.加 annotation @SafeVarargs
  122. 2.加 annotation @SuppressWarnings({"unchecked""varargs"})  
  123. 3.使用編譯器引數 –Xlint:varargs;  
  124. 1.8 資訊更豐富的回溯追蹤 就是上面trytry語句和裡面的語句同時丟擲異常時,異常棧的資訊  
  125.     java.io.IOException    
  126.     §?      at Suppress.write(Suppress.java:19)    
  127.     §?      at Suppress.main(Suppress.java:8)    
  128.     §?      Suppressed:  java.io.IOException   
  129.     §?          at Suppress.close(Suppress.java:24)   
  130.     §?          at Suppress.main(Suppress.java:9)    
  131.     §?      Suppressed:  java.io.IOException   
  132.     §?          at  Suppress.close(Suppress.java:24)    
  133.     §?          at  Suppress.main(Suppress.java:9)   
  134. 2. NIO2的一些新特性  
  135. 1.java.nio.file 和java.nio.file.attribute包 支援更詳細屬性,比如許可權,所有者   
  136. 2.  symbolic and hard links支援   
  137. 3. Path訪問檔案系統,Files支援各種檔案操作   
  138. 4.高效的訪問metadata資訊   
  139. 5.遞迴查詢檔案樹,檔案擴充套件搜尋   
  140. 6.檔案系統修改通知機制   
  141. 7.File類操作API相容   
  142. 8.檔案隨機訪問增強 mapping a region,locl a region,絕對位置讀取   
  143. 9. AIO Reactor(基於事件)和Proactor   
  144.   下面列一些示例:  
  145. 2.1IO and New IO 監聽檔案系統變化通知   
  146. 通過FileSystems.getDefault().newWatchService()獲取watchService,然後將需要監聽的path目錄註冊到這個watchservice中,對於這個目錄的檔案修改,新增,刪除等實踐可以配置,然後就自動能監聽到響應的事件。  
  147. private WatchService watcher;   
  148. public TestWatcherService(Path path) throws IOException {  
  149.     watcher = FileSystems.getDefault().newWatchService();  
  150.     path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);  
  151.     }   
  152. publicvoid handleEvents() throws InterruptedException {  
  153. while (true) {  
  154.     WatchKey key = watcher.take();  
  155. for (WatchEvent<?> event : key.pollEvents()) {  
  156.     WatchEvent.Kind kind = event.kind();  
  157. if (kind == OVERFLOW) {// 事件可能lost or discarded
  158. continue;  
  159.     }  
  160.     WatchEvent<Path> e = (WatchEvent<Path>) event;  
  161.     Path fileName = e.context();  
  162.     System.out.printf("Event %s has happened,which fileName is %s%n",kind.name(), fileName);  
  163.     }  
  164. if (!key.reset()) {  
  165. break;  
  166.     }  
  167. 2.2 IO and New IO遍歷檔案樹 ,通過繼承SimpleFileVisitor類,實現事件遍歷目錄樹的操作,然後通過Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);這個API來遍歷目錄樹  
  168. privatevoid workFilePath() {  
  169.     Path listDir = Paths.get("/tmp"); // define the starting file 
  170.     ListTree walk = new ListTree();  
  171.     …Files.walkFileTree(listDir, walk);…  
  172. // 遍歷的時候跟蹤連結
  173.     EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);  
  174. try {  
  175.     Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);  
  176.     } catch (IOException e) {  
  177.     System.err.println(e);  
  178.     }  
  179. class ListTree extends SimpleFileVisitor<Path> {// NIO2 遞迴遍歷檔案目錄的介面 
  180. @Override
  181. public FileVisitResult postVisitDirectory(Path dir, IOException exc) {  
  182.     System.out.println("Visited directory: " + dir.toString());  
  183. return FileVisitResult.CONTINUE;  
  184.     }   
  185. @Override
  186. public FileVisitResult visitFileFailed(Path file, IOException exc) {  
  187.     System.out.println(exc);  
  188. return FileVisitResult.CONTINUE;  
  189.     }  
  190.     }  
  191. 2.3 AIO非同步IO 檔案和網路 非同步IO在java   
  192.  NIO2實現了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等實現,關於同步阻塞IO,同步非阻塞IO,非同步阻塞IO和非同步非阻塞IO在ppt的這頁上下面備註有說明,有興趣的可以深入瞭解下。Java NIO2中就實現了作業系統的非同步非阻塞IO。  
  193. // 使用AsynchronousFileChannel.open(path, withOptions(),  
  194. // taskExecutor))這個API對非同步檔案IO的處理  
  195. publicstaticvoid asyFileChannel2() {    
  196. finalint THREADS = 5;    
  197.             ExecutorService taskExecutor = Executors.newFixedThreadPool(THREADS);    
  198.             String encoding = System.getProperty("file.encoding");    
  199.             List<Future<ByteBuffer>> list = new ArrayList<>();    
  200. int sheeps = 0;    
  201.             Path path = Paths.get("/tmp",    
  202. "store.txt");    
  203. try (AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel    
  204.                     .open(path, withOptions(), taskExecutor)) {    
  205. for (int i = 0; i < 50; i++) {    
  206.                     Callable<ByteBuffer> worker = new Callable<ByteBuffer>() {    
  207. @Override
  208. public ByteBuffer call() throws Exception {    
  209.                             ByteBuffer buffer = ByteBuffer    
  210.                                     .allocateDirect(ThreadLocalRandom.current()    
  211.                                             .nextInt(100200));    
  212.                             asynchronousFileChannel.read(buffer, ThreadLocalRandom    
  213.     ……  
  214. 3. JDBC 4.1
  215. 3.1.可以使用try-with-resources自動關閉Connection, ResultSet, 和 Statement資源物件   
  216. 3.2. RowSet 1.1:引入RowSetFactory介面和RowSetProvider類,可以建立JDBC driver支援的各種 row sets,這裡的rowset實現其實就是將sql語句上的一些操作轉為方法的操作,封裝了一些功能。  
  217. 3.3. JDBC-ODBC驅動會在jdk8中刪除   
  218. try (Statement stmt = con.createStatement()) {   
  219.      RowSetFactory aFactory = RowSetProvider.newFactory();  
  220.       CachedRowSet crs = aFactory.createCachedRowSet();  
  221.      RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl"null);  
  222.     WebRowSet wrs = rsf.createWebRowSet();  
  223.     createCachedRowSet   
  224.     createFilteredRowSet   
  225.     createJdbcRowSet   
  226.     createJoinRowSet   
  227.     createWebRowSet   
  228. 4. 併發工具增強   
  229. 4.1.fork-join   
  230.  最大的增強,充分利用多核特性,將大問題分解成各個子問題,由多個cpu可以同時解決多個子問題,最後合併結果,繼承RecursiveTask,實現compute方法,然後呼叫fork計算,最後用join合併結果。  
  231. class Fibonacci extends RecursiveTask<Integer> {  
  232. finalint n;  
  233.     Fibonacci(int n) {  
  234. this.n = n;  
  235.     }  
  236. privateint compute(int small) {  
  237. finalint[] results = { 1123581321345589 };  
  238. return results[small];  
  239.     }  
  240. public Integer compute() {  
  241. if (n <= 10) {  
  242. return compute(n);  
  243.     }  
  244.     Fibonacci f1 = new Fibonacci(n - 1);  
  245.     Fibonacci f2 = new Fibonacci(n - 2);  
  246.     System.out.println("fork new thread for " + (n - 1));  
  247.     f1.fork();  
  248.     System.out.println("fork new thread for " + (n - 2));  
  249.     f2.fork();  
  250. return f1.join() + f2.join();  
  251.     }  
  252.     }   
  253. 4.2.ThreadLocalRandon 併發下隨機數生成類,保證併發下的隨機數生成的執行緒安全,實際上就是使用threadlocal  
  254. finalint MAX = 100000;  
  255.     ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();  
  256. long start = System.nanoTime();  
  257. for (int i = 0; i < MAX; i++) {  
  258.     threadLocalRandom.nextDouble();  
  259.     }  
  260. long end = System.nanoTime() - start;  
  261.     System.out.println("use time1 : " + end);  
  262. long start2 = System.nanoTime();  
  263. for (int i = 0; i < MAX; i++) {  
  264.     Math.random();  
  265.     }  
  266. long end2 = System.nanoTime() - start2;  
  267.     System.out.println("use time2 : " + end2);   
  268. 4.3. phaser 類似cyclebarrier和countdownlatch,不過可以動態新增資源減少資源  
  269. void runTasks(List<Runnable> tasks) {  
  270. final Phaser phaser = new Phaser(1); // "1" to register self
  271. // create and start threads
  272. for (final Runnable task : tasks) {  
  273.     phaser.register();  
  274. new Thread() {  
  275. publicvoid run() {  
  276.     phaser.arriveAndAwaitAdvance(); // await all creation
  277.     task.run();  
  278.     }  
  279.     }.start();  
  280.     }  
  281. // allow threads to start and deregister self
  282.     phaser.arriveAndDeregister();  
  283.     }   
  284. 5. Networking增強   
  285. 新增URLClassLoader close方法,可以及時關閉資源,後續重新載入class檔案時不會導致資源被佔用或者無法釋放問題  
  286. URLClassLoader.newInstance(new URL[]{}).close();  
  287. 新增Sockets Direct Protocol  
  288. 繞過作業系統的資料拷貝,將資料從一臺機器的記憶體資料通過網路直接傳輸到另外一臺機器的記憶體中   
  289. 6. Multithreaded Custom Class Loaders    
  290.     解決併發下載入class可能導致的死鎖問題,這個是jdk1.6的一些新版本就解決了,jdk7也做了一些優化。有興趣可以仔細從官方文件詳細瞭解  
  291. jdk7前:  
  292.     Class Hierarchy:              
  293. class A extends B  
  294. class C extends D  
  295.     ClassLoader Delegation Hierarchy:  
  296.     Custom Classloader CL1:  
  297.       directly loads class A   
  298.       delegates to custom ClassLoader CL2 forclass B  
  299.     Custom Classloader CL2:  
  300.       directly loads class C  
  301.       delegates to custom ClassLoader CL1 forclass D  
  302.     Thread 1:  
  303.       Use CL1 to load class A (locks CL1)  
  304.         defineClass A triggers  
  305.           loadClass B (try to lock CL2)  
  306.     Thread 2:  
  307.       Use CL2 to load class C (locks CL2)  
  308.         defineClass C triggers  
  309.           loadClass D (try to lock CL1)  
  310.     Synchronization in the ClassLoader class wa   
  311. jdk7  
  312.     Thread 1:  
  313.       Use CL1 to load class A (locks CL1+A)  
  314.         defineClass A triggers  
  315.           loadClass B (locks CL2+B)  
  316.     Thread 2:  
  317.       Use CL2 to load class C (locks CL2+C)  
  318.         defineClass C triggers  
  319.           loadClass D (locks CL1+D)   
  320. 7. Security 增強   
  321. 7.1.提供幾種 ECC-based algorithms (ECDSA/ECDH) Elliptic Curve Cryptography (ECC)  
  322. 7.2.禁用CertPath Algorithm Disabling  
  323. 7.3. JSSE (SSL/TLS)的一些增強   
  324. 8. Internationalization 增強 增加了對一些編碼的支援和增加了一些顯示方面的編碼設定等  
  325. 1. New Scripts and Characters from Unicode 6.0.0
  326. 2. Extensible Support for ISO 4217 Currency Codes  
  327.     Currency類新增:        
  328.            getAvailableCurrencies   
  329.            getNumericCode   
  330.            getDisplayName   
  331.            getDisplayName(Locale)  
  332. 3. Category Locale Support  
  333.      getDefault(Locale.Category)FORMAT  DISPLAY   
  334. 4. Locale Class Supports BCP47 and UTR35  
  335.            UNICODE_LOCALE_EXTENSION  
  336.            PRIVATE_USE_EXTENSION  
  337.            Locale.Builder   
  338.            getExtensionKeys()  
  339.            getExtension(char)  
  340.            getUnicodeLocaleType(String  
  341.             ……  
  342. 5. New NumericShaper Methods  
  343.     NumericShaper.Range   
  344.     getShaper(NumericShaper.Range)   
  345.     getContextualShaper(Set<NumericShaper.Range>)……   
  346. 9.jvm方面的一些特性增強,下面這些特性有些在jdk6中已經存在,這裡做了一些優化和增強。  
  347. 1.Jvm支援非java的語言 invokedynamic 指令   
  348. 2. Garbage-First Collector 適合server端,多處理器下大記憶體,將heap分成大小相等的多個區域,mark階段檢測每個區域的存活物件,compress階段將存活物件最小的先做回收,這樣會騰出很多空閒區域,這樣併發回收其他區域就能減少停止時間,提高吞吐量。   
  349. 3. HotSpot效能增強   
  350.     Tiered Compilation  -XX:+UseTieredCompilation 多層編譯,對於經常呼叫的程式碼會直接編譯程原生代碼,提高效率  
  351.    Compressed Oops  壓縮物件指標,減少空間使用  
  352.   Zero-Based Compressed Ordinary Object Pointers (oops) 進一步優化零基壓縮物件指標,進一步壓縮空間  
  353. 4. Escape Analysis  逃逸分析,對於只是在一個方法使用的一些變數,可以直接將物件分配到棧上,方法執行完自動釋放記憶體,而不用通過棧的物件引用引用堆中的物件,那麼對於物件的回收可能不是那麼及時。  
  354. 5. NUMA Collector Enhancements    
  355. NUMA(Non Uniform Memory Access),NUMA在多種計算機系統中都得到實現,簡而言之,就是將記憶體分段訪問,類似於硬碟的RAID,Oracle中的分簇   
  356. 10. Java 2D Enhancements  
  357. 1. XRender-Based Rendering Pipeline -Dsun.java2d.xrender=True  
  358. 2. Support for OpenType/CFF Fonts GraphicsEnvironment.getAvailableFontFamilyNames   
  359. 3. TextLayout Support for Tibetan Script  
  360. 4. Support for Linux Fonts  
  361. 11. Swing Enhancements  
  362. 1.  JLayer   
  363. 2.  Nimbus Look & Feel  
  364. 3.  Heavyweight and Lightweight Components  
  365. 4.  Shaped and Translucent Windows  
  366. 5.  Hue-Saturation-Luminance (HSL) Color Selection in JColorChooser Class  
  367. 12. Jdk8 lambda表示式 最大的新增的特性,不過在很多動態語言中都已經原生支援。  
  368. 原來這麼寫:  
  369.     btn.setOnAction(new EventHandler<ActionEvent>() {   
  370. @Override
  371. publicvoid handle(ActionEvent event) {   
  372.             System.out.println("Hello World!");   
  373.         }   
  374.     });   
  375. jdk8直接可以這麼寫:  
  376.     btn.setOnAction(   
  377.         event -> System.out.println("Hello World!")   
  378.     );     
  379. 更多示例:  
  380. publicclass Utils {   
  381. publicstaticint compareByLength(String in, String out){   
  382. return in.length() - out.length();   
  383.         }   
  384.     }   
  385. publicclass MyClass {   
  386. publicvoid doSomething() {   
  387.             String[] args = new String[] {"microsoft","apple","linux","oracle"}   
  388.             Arrays.sort(args, Utils::compareByLength);   
  389.         }    
  390.     }    
  391. 13.jdk8的一些其他特性,當然jdk8的增強功能還有很多,大家可以參考http://openjdk.java.net/projects/jdk8/
  392. 用Metaspace代替PermGen   
  393. 動態擴充套件,可以設定最大值,限制於本地記憶體的大小   
  394. Parallel array sorting 新APIArrays#parallelSort.  
  395.     New Date & Time API  
  396.     Clock clock = Clock.systemUTC(); //return the current time based on your system clock and set to UTC.
  397.     Clock clock = Clock.systemDefaultZone(); //return time based on system clock zone 
  398. long time = clock.millis(); //time in milliseconds from January 1st, 1970