Java 5~11各个版本新特性史上最全总结
Java 5
Java5開發代號為Tiger(老虎),于2004-09-30發行
特性列表
-
泛型
-
枚舉
-
自動裝箱拆箱
-
可變參數
-
注解
-
foreach循環(增強for、for/in)
-
靜態導入
-
格式化(System.out.println 支持%s %d等格式化輸出)
-
線程框架/數據結構 JUC
-
Arrays工具類/StringBuilder/instrument
1、泛型
所謂類型擦除指的就是Java源碼中的范型信息只允許停留在編譯前期,而編譯后的字節碼文件中將不再保留任何的范型信息。也就是說,范型信息在編譯時將會被全部刪除,其中范型類型的類型參數則會被替換為Object類型,并在實際使用時強制轉換為指定的目標數據類型。而C++中的模板則會在編譯時將模板類型中的類型參數根據所傳遞的指定數據類型生成相對應的目標代碼。
Map<Integer,?Integer>?squares?=?new?HashMap<Integer,?Integer>();通配符類型:避免unchecked警告,問號表示任何類型都可以接受
public?void?printList(List<?>?list,?PrintStream?out)?throws?IOException?{for?(Iterator<?>?i?=?list.iterator();?i.hasNext();?)?{out.println(i.next().toString());}}限制類型
public?static?<A?extends?Number>?double?sum(Box<A>?box1,Box<A>?box2){double?total?=?0;for?(Iterator<A>?i?=?box1.contents.iterator();?i.hasNext();?)?{total?=?total?+?i.next().doubleValue();}for?(Iterator<A>?i?=?box2.contents.iterator();?i.hasNext();?)?{total?=?total?+?i.next().doubleValue();}return?total;}2、枚舉
EnumMap
public?void?testEnumMap(PrintStream?out)?throws?IOException?{//?Create?a?map?with?the?key?and?a?String?messageEnumMap<AntStatus,?String>?antMessages?=new?EnumMap<AntStatus,?String>(AntStatus.class);//?Initialize?the?mapantMessages.put(AntStatus.INITIALIZING,?"Initializing?Ant...");antMessages.put(AntStatus.COMPILING,????"Compiling?Java?classes...");antMessages.put(AntStatus.COPYING,??????"Copying?files...");antMessages.put(AntStatus.JARRING,??????"JARring?up?files...");antMessages.put(AntStatus.ZIPPING,??????"ZIPping?up?files...");antMessages.put(AntStatus.DONE,?????????"Build?complete.");antMessages.put(AntStatus.ERROR,????????"Error?occurred.");//?Iterate?and?print?messagesfor?(AntStatus?status?:?AntStatus.values()?)?{out.println("For?status?"?+?status?+?",?message?is:?"?+antMessages.get(status));}}switch枚舉
public?String?getDescription()?{switch(this)?{case?ROSEWOOD:??????return?"Rosewood?back?and?sides";case?MAHOGANY:??????return?"Mahogany?back?and?sides";case?ZIRICOTE:??????return?"Ziricote?back?and?sides";case?SPRUCE:????????return?"Sitka?Spruce?top";case?CEDAR:?????????return?"Wester?Red?Cedar?top";case?AB_ROSETTE:????return?"Abalone?rosette";case?AB_TOP_BORDER:?return?"Abalone?top?border";case?IL_DIAMONDS:???return?"Diamonds?and?squares?fretboard?inlay";case?IL_DOTS:return?"Small?dots?fretboard?inlay";default:?return?"Unknown?feature";}}3、自動拆箱/裝箱
將primitive類型轉換成對應的wrapper類型:Boolean、Byte、Short、Character、Integer、Long、Float、Double
4、可變參數
private?String?print(Object...?values)?{StringBuilder?sb?=?new?StringBuilder();for?(Object?o?:?values)?{sb.append(o.toString()).append("?");}return?sb.toString();}5、注解
Inherited表示該注解是否對類的子類繼承的方法等起作用
@Documented @Inherited @Retention(RetentionPolicy.RUNTIME) public?@interface?InProgress?{?}Target類型
Rentation表示annotation是否保留在編譯過的class文件中還是在運行時可讀。
6、增強for循環 for/in
for/in循環辦不到的事情:
(1)遍歷同時獲取index
(2)集合逗號拼接時去掉最后一個
(3)遍歷的同時刪除元素
7、靜態導入
import?static?java.lang.System.err; import?static?java.lang.System.out;err.println(msg);?8、print輸出格式化
System.out.println("Line?%d:?%s%n",?i++,?line);9、并發支持(JUC)
線程池
uncaught exception(可以抓住多線程內的異常)
blocking queue(BlockingQueue)
JUC類庫
10、Arrays、Queue、線程安全StringBuilder
Arrays工具類
Arrays.sort(myArray); Arrays.toString(myArray) Arrays.binarySearch(myArray,?98) Arrays.deepToString(ticTacToe) Arrays.deepEquals(ticTacToe,?ticTacToe3)Queue
避開集合的add/remove操作,使用offer、poll操作(不拋異常)
Queue接口與List、Set同一級別,都是繼承了Collection接口。LinkedList實現了Deque接口。
Queue?q?=?new?LinkedList();?//采用它來實現queueOverride返回類型
單線程StringBuilder
java.lang.instrument
?
Java 6
Java6開發代號為Mustang(野馬),于2006-12-11發行。評價:雞肋的版本,有JDBC4.0更新、Complier API、WebSevice支持的加強等更新。
1、Web Services
優先支持編寫 XML web service 客戶端程序。你可以用過簡單的annotaion將你的API發布成.NET交互的web services. Mustang 添加了新的解析和 XML 在 Java object-mapping APIs中, 之前只在Java EE平臺實現或者Java Web Services Pack中提供.
2、Scripting(開啟JS的支持,算是比較有用的)
現在你可以在Java源代碼中混入JavaScript了,這對開發原型很有有用,你也可以插入自己的腳本引擎。
3、Database
Mustang 將聯合綁定 Java DB (Apache Derby). JDBC 4.0 增加了許多特性例如支持XML作為SQL數據類型,更好的集成Binary Large OBjects (BLOBs) 和 Character Large OBjects (CLOBs) .
4、More Desktop APIs
GUI 開發者可以有更多的技巧來使用 SwingWorker utility ,以幫助GUI應用中的多線程。, JTable 分類和過濾,以及添加splash閃屏。
很顯然,這對于主攻服務器開發的Java來說,并沒有太多吸引力
5、Monitoring and Management.
綁定了不是很知名的 memory-heap 分析工具Jhat 來查看內核導出。
6、Compiler Access(這個很厲害)
compiler API提供編程訪問javac,可以實現進程內編譯,動態產生Java代碼。
7、Pluggable Annotation
8、Desktop Deployment.
Swing擁有更好的 look-and-feel , LCD 文本呈現, 整體GUI性能的提升。Java應用程序可以和本地平臺更好的集成,例如訪問平臺的系統托盤和開始菜單。Mustang將Java插件技術和Java Web Start引擎統一了起來。
9、Security
XML-數字簽名(XML-DSIG) APIs 用于創建和操縱數字簽名); 新的方法來訪問本地平臺的安全服務
10、The -ilities(很好的習慣)
質量,兼容性,穩定性。 80,000 test cases 和數百萬行測試代碼(只是測試活動中的一個方面). Mustang 的快照發布已經被下載15個月了,每一步中的Bug都被修復了,表現比J2SE 5還要好。
?
Java 7
特性列表
-
switch中添加對String類型的支持
-
數字字面量的改進 / 數值可加下劃
-
異常處理(捕獲多個異常) try-with-resources
-
增強泛型推斷
-
JSR203 NIO2.0(AIO)新IO的支持
-
JSR292與InvokeDynamic指令
-
Path接口、DirectoryStream、Files、WatchService(重要接口更新)
-
fork/join framework
1、switch中添加對String類型的支持
???????String?title?=?"";??switch?(gender)?{??case?"男":??title?=?name?+?"?先生";??break;??case?"女":??title?=?name?+?"?女士";??break;??default:??title?=?name;??}??return?title;??編譯器在編譯時先做處理:
①case僅僅有一種情況。直接轉成if。
②假設僅僅有一個case和default,則直接轉換為if…else…。
③有多個case。先將String轉換為hashCode,然后相應的進行處理,JavaCode在底層兼容Java7曾經版本號。
2、數字字面量的改進
Java7前支持十進制(123)、八進制(0123)、十六進制(0X12AB)
Java7添加二進制表示(0B11110001、0b11110001)
數字中可加入分隔符
Java7中支持在數字量中間添加’_'作為分隔符。更直觀,如(12_123_456)。下劃線僅僅能在數字中間。編譯時編譯器自己主動刪除數字中的下劃線。
3、異常處理(捕獲多個異常) try-with-resources
catch子句能夠同一時候捕獲多個異常
public?void?testSequence()?{??try?{??Integer.parseInt("Hello");??}??catch?(NumberFormatException?|?RuntimeException?e)?{??//使用'|'切割,多個類型,一個對象e??}??}?try-with-resources語句
Java7之前須要在finally中關閉socket、文件、數據庫連接等資源;
Java7中在try語句中申請資源,實現資源的自己主動釋放(資源類必須實現java.lang.AutoCloseable接口,一般的文件、數據庫連接等均已實現該接口,close方法將被自己主動調用)。
4、增強泛型推斷
Map<String,?List<String>>?map?=?new?HashMap<String,?List<String>>();??Java7之后可以簡單的這么寫
Map<String,?List<String>>?anagrams?=?new?HashMap<>();?5、NIO2.0(AIO)新IO的支持
bytebuffer
public?class?ByteBufferUsage?{public?void?useByteBuffer()?{ByteBuffer?buffer?=?ByteBuffer.allocate(32);buffer.put((byte)1);buffer.put(new?byte[3]);buffer.putChar('A');buffer.putFloat(0.0f);buffer.putLong(10,?100L);System.out.println(buffer.getChar(4));System.out.println(buffer.remaining());}public?void?byteOrder()?{ByteBuffer?buffer?=?ByteBuffer.allocate(4);buffer.putInt(1);buffer.order(ByteOrder.LITTLE_ENDIAN);buffer.getInt(0);?//值為16777216}public?void?compact()?{ByteBuffer?buffer?=?ByteBuffer.allocate(32);buffer.put(new?byte[16]);buffer.flip();buffer.getInt();buffer.compact();int?pos?=?buffer.position();}public?void?viewBuffer()?{ByteBuffer?buffer?=?ByteBuffer.allocate(32);buffer.putInt(1);IntBuffer?intBuffer?=?buffer.asIntBuffer();intBuffer.put(2);int?value?=?buffer.getInt();?//值為2}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?{ByteBufferUsage?bbu?=?new?ByteBufferUsage();bbu.useByteBuffer();bbu.byteOrder();bbu.compact();bbu.viewBuffer();} }filechannel
public?class?FileChannelUsage?{public?void?openAndWrite()?throws?IOException?{FileChannel?channel?=?FileChannel.open(Paths.get("my.txt"),?StandardOpenOption.CREATE,?StandardOpenOption.WRITE);ByteBuffer?buffer?=?ByteBuffer.allocate(64);buffer.putChar('A').flip();channel.write(buffer);}public?void?readWriteAbsolute()?throws?IOException?{FileChannel?channel?=?FileChannel.open(Paths.get("absolute.txt"),?StandardOpenOption.READ,?StandardOpenOption.CREATE,?StandardOpenOption.WRITE);ByteBuffer?writeBuffer?=?ByteBuffer.allocate(4).putChar('A').putChar('B');writeBuffer.flip();channel.write(writeBuffer,?1024);ByteBuffer?readBuffer?=?ByteBuffer.allocate(2);channel.read(readBuffer,?1026);readBuffer.flip();char?result?=?readBuffer.getChar();?//值為'B'}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?throws?IOException?{FileChannelUsage?fcu?=?new?FileChannelUsage();fcu.openAndWrite();fcu.readWriteAbsolute();} }6、JSR292與InvokeDynamic
JSR 292: Supporting Dynamically Typed Languages on the JavaTM Platform,支持在JVM上運行動態類型語言。在字節碼層面支持了InvokeDynamic。
public?class?ThreadPoolManager?{private?final?ScheduledExecutorService?stpe?=?Executors.newScheduledThreadPool(2);private?final?BlockingQueue<WorkUnit<String>>?lbq;public?ThreadPoolManager(BlockingQueue<WorkUnit<String>>?lbq_)?{lbq?=?lbq_;}public?ScheduledFuture<?>?run(QueueReaderTask?msgReader)?{msgReader.setQueue(lbq);return?stpe.scheduleAtFixedRate(msgReader,?10,?10,?TimeUnit.MILLISECONDS);}private?void?cancel(final?ScheduledFuture<?>?hndl)?{stpe.schedule(new?Runnable()?{public?void?run()?{hndl.cancel(true);}},?10,?TimeUnit.MILLISECONDS);}/***?使用傳統的反射api*/public?Method?makeReflective()?{Method?meth?=?null;try?{Class<?>[]?argTypes?=?new?Class[]{ScheduledFuture.class};meth?=?ThreadPoolManager.class.getDeclaredMethod("cancel",?argTypes);meth.setAccessible(true);}?catch?(IllegalArgumentException?|?NoSuchMethodException|?SecurityException?e)?{e.printStackTrace();}return?meth;}/***?使用代理類*?@return*/public?CancelProxy?makeProxy()?{return?new?CancelProxy();}/***?使用Java7的新api,MethodHandle*?invoke?virtual?動態綁定后調用?obj.xxx*?invoke?special?靜態綁定后調用?super.xxx*?@return*/public?MethodHandle?makeMh()?{MethodHandle?mh;MethodType?desc?=?MethodType.methodType(void.class,?ScheduledFuture.class);try?{mh?=?MethodHandles.lookup().findVirtual(ThreadPoolManager.class,"cancel",?desc);}?catch?(NoSuchMethodException?|?IllegalAccessException?e)?{throw?(AssertionError)?new?AssertionError().initCause(e);}return?mh;}public?static?class?CancelProxy?{private?CancelProxy()?{}public?void?invoke(ThreadPoolManager?mae_,?ScheduledFuture<?>?hndl_)?{mae_.cancel(hndl_);}} }調用invoke
public?class?ThreadPoolMain?{/***?如果被繼承,還能在靜態上下文尋找正確的class*/private?static?final?Logger?logger?=?LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());private?ThreadPoolManager?manager;public?static?void?main(String[]?args)?{ThreadPoolMain?main?=?new?ThreadPoolMain();main.run();}private?void?cancelUsingReflection(ScheduledFuture<?>?hndl)?{Method?meth?=?manager.makeReflective();try?{System.out.println("With?Reflection");meth.invoke(hndl);}?catch?(IllegalAccessException?|?IllegalArgumentException|?InvocationTargetException?e)?{e.printStackTrace();}}private?void?cancelUsingProxy(ScheduledFuture<?>?hndl)?{CancelProxy?proxy?=?manager.makeProxy();System.out.println("With?Proxy");proxy.invoke(manager,?hndl);}private?void?cancelUsingMH(ScheduledFuture<?>?hndl)?{MethodHandle?mh?=?manager.makeMh();try?{System.out.println("With?Method?Handle");mh.invokeExact(manager,?hndl);}?catch?(Throwable?e)?{e.printStackTrace();}}private?void?run()?{BlockingQueue<WorkUnit<String>>?lbq?=?new?LinkedBlockingQueue<>();manager?=?new?ThreadPoolManager(lbq);final?QueueReaderTask?msgReader?=?new?QueueReaderTask(100)?{@Overridepublic?void?doAction(String?msg_)?{if?(msg_?!=?null)System.out.println("Msg?recvd:?"?+?msg_);}};ScheduledFuture<?>?hndl?=?manager.run(msgReader);cancelUsingMH(hndl);//?cancelUsingProxy(hndl);//?cancelUsingReflection(hndl);} }7、Path接口(重要接口更新)
Path
public?class?PathUsage?{public?void?usePath()?{Path?path1?=?Paths.get("folder1",?"sub1");Path?path2?=?Paths.get("folder2",?"sub2");path1.resolve(path2);?//folder1\sub1\folder2\sub2path1.resolveSibling(path2);?//folder1\folder2\sub2path1.relativize(path2);?//..\..\folder2\sub2path1.subpath(0,?1);?//folder1path1.startsWith(path2);?//falsepath1.endsWith(path2);?//falsePaths.get("folder1/./../folder2/my.text").normalize();?//folder2\my.text}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?{PathUsage?usage?=?new?PathUsage();usage.usePath();} }DirectoryStream
public?class?ListFile?{public?void?listFiles()?throws?IOException?{Path?path?=?Paths.get("");try?(DirectoryStream<Path>?stream?=?Files.newDirectoryStream(path,?"*.*"))?{for?(Path?entry:?stream)?{//使用entrySystem.out.println(entry);}}}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?throws?IOException?{ListFile?listFile?=?new?ListFile();listFile.listFiles();} }Files
public?class?FilesUtils?{public?void?manipulateFiles()?throws?IOException?{Path?newFile?=?Files.createFile(Paths.get("new.txt").toAbsolutePath());List<String>?content?=?new?ArrayList<String>();content.add("Hello");content.add("World");Files.write(newFile,?content,?Charset.forName("UTF-8"));Files.size(newFile);byte[]?bytes?=?Files.readAllBytes(newFile);ByteArrayOutputStream?output?=?new?ByteArrayOutputStream();Files.copy(newFile,?output);Files.delete(newFile);}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?throws?IOException?{FilesUtils?fu?=?new?FilesUtils();fu.manipulateFiles();} }WatchService
public?class?WatchAndCalculate?{public?void?calculate()?throws?IOException,?InterruptedException?{WatchService?service?=?FileSystems.getDefault().newWatchService();Path?path?=?Paths.get("").toAbsolutePath();path.register(service,?StandardWatchEventKinds.ENTRY_CREATE);while?(true)?{WatchKey?key?=?service.take();for?(WatchEvent<?>?event?:?key.pollEvents())?{Path?createdPath?=?(Path)?event.context();createdPath?=?path.resolve(createdPath);long?size?=?Files.size(createdPath);System.out.println(createdPath?+?"?==>?"?+?size);}key.reset();}}/***?@param?args?the?command?line?arguments*/public?static?void?main(String[]?args)?throws?Throwable?{WatchAndCalculate?wc?=?new?WatchAndCalculate();wc.calculate();} }8、fork/join計算框架
Java7提供的一個用于并行執行任務的框架,是一個把大任務分割成若干個小任務,最終匯總每個小任務結果后得到大任務結果的框架。
該框架為Java8的并行流打下了堅實的基礎
?
Java 8
Java 8可謂是自Java 5以來最具革命性的版本了,她在語言、編譯器、類庫、開發工具以及Java虛擬機等方面都帶來了不少新特性。
一、Lambda表達式
Lambda表達式可以說是Java 8最大的賣點,她將函數式編程引入了Java。Lambda允許把函數作為一個方法的參數,或者把代碼看成數據。
一個Lambda表達式可以由用逗號分隔的參數列表、–>符號與函數體三部分表示。例如:
Arrays.asList(?"p",?"k",?"u","f",?"o",?"r","k").forEach(?e?->?System.out.println(?e?)?);為了使現有函數更好的支持Lambda表達式,Java 8引入了函數式接口的概念。函數式接口就是只有一個方法的普通接口。java.lang.Runnable與java.util.concurrent.Callable是函數式接口最典型的例子。為此,Java 8增加了一種特殊的注解@FunctionalInterface
二、接口的默認方法與靜態方法
我們可以在接口中定義默認方法,使用default關鍵字,并提供默認的實現。所有實現這個接口的類都會接受默認方法的實現,除非子類提供的自己的實現。例如:
public?interface?DefaultFunctionInterface?{default?String?defaultFunction()?{return?"default?function";}}我們還可以在接口中定義靜態方法,使用static關鍵字,也可以提供實現。例如:
public?interface?StaticFunctionInterface?{static?String?staticFunction()?{return?"static?function";}}接口的默認方法和靜態方法的引入,其實可以認為引入了C++中抽象類的理念,以后我們再也不用在每個實現類中都寫重復的代碼了。
三、方法引用(含構造方法引用)
通常與Lambda表達式聯合使用,可以直接引用已有Java類或對象的方法。一般有四種不同的方法引用:
構造器引用。語法是Class::new,或者更一般的Class< T >::new,要求構造器方法是沒有參數;
靜態方法引用。語法是Class::static_method,要求接受一個Class類型的參數;
特定類的任意對象方法引用。它的語法是Class::method。要求方法是沒有參數的;
特定對象的方法引用,它的語法是instance::method。要求方法接受一個參數,與3不同的地方在于,3是在列表元素上分別調用方法,而4是在某個對象上調用方法,將列表元素作為參數傳入;
四、重復注解
在Java 5中使用注解有一個限制,即相同的注解在同一位置只能聲明一次。Java 8引入重復注解,這樣相同的注解在同一地方也可以聲明多次。重復注解機制本身需要用@Repeatable注解。Java 8在編譯器層做了優化,相同注解會以集合的方式保存,因此底層的原理并沒有變化。
五、擴展注解的支持(類型注解)
Java 8擴展了注解的上下文,幾乎可以為任何東西添加注解,包括局部變量、泛型類、父類與接口的實現,連方法的異常也能添加注解。
private?@NotNull?String?name;六、Optional
Java 8引入Optional類來防止空指針異常,Optional類最先是由Google的Guava項目引入的。Optional類實際上是個容器:它可以保存類型T的值,或者保存null。使用Optional類我們就不用顯式進行空指針檢查了。
七、Stream
Stream API是把真正的函數式編程風格引入到Java中。其實簡單來說可以把Stream理解為MapReduce,當然Google的MapReduce的靈感也是來自函數式編程。她其實是一連串支持連續、并行聚集操作的元素。從語法上看,也很像linux的管道、或者鏈式編程,代碼寫起來簡潔明了,非常酷帥!
八、Date/Time API (JSR 310)
Java 8新的Date-Time API (JSR 310)受Joda-Time的影響,提供了新的java.time包,可以用來替代 java.util.Date和java.util.Calendar。一般會用到Clock、LocaleDate、LocalTime、LocaleDateTime、ZonedDateTime、Duration這些類,對于時間日期的改進還是非常不錯的。
九、JavaScript引擎Nashorn
Nashorn允許在JVM上開發運行JavaScript應用,允許Java與JavaScript相互調用。
十、Base64
在Java 8中,Base64編碼成為了Java類庫的標準。Base64類同時還提供了對URL、MIME友好的編碼器與解碼器。
說在后面
除了這十大特性,還有另外的一些新特性:
更好的類型推測機制:Java 8在類型推測方面有了很大的提高,這就使代碼更整潔,不需要太多的強制類型轉換了。
編譯器優化:Java 8將方法的參數名加入了字節碼中,這樣在運行時通過反射就能獲取到參數名,只需要在編譯時使用-parameters參數。
并行(parallel)數組:支持對數組進行并行處理,主要是parallelSort()方法,它可以在多核機器上極大提高數組排序的速度。
并發(Concurrency):在新增Stream機制與Lambda的基礎之上,加入了一些新方法來支持聚集操作。
Nashorn引擎jjs:基于Nashorn引擎的命令行工具。它接受一些JavaScript源代碼為參數,并且執行這些源代碼。
類依賴分析器jdeps:可以顯示Java類的包級別或類級別的依賴。
JVM的PermGen空間被移除:取代它的是Metaspace(JEP 122)。
?
Java 9
經過4次跳票,歷經曲折的java 9 終于終于在2017年9月21日發布(距離上個版本足足3年半時間)java 9 提供了超過 150 項新功能特性,包括備受期待的模塊化系統、可交互的 REPL 工具:jshell,JDK 編譯工具,Java 公共 API 和私有代碼,以及安全增強、擴展提升、性能管理改善等。可以說 Java 9 是一個龐大的系統工程,完全做了一個整體改變。但本博文只介紹最重要的十大新特性
特性列表
-
平臺級modularity(原名:Jigsaw) 模塊化系統
-
Java 的 REPL 工具: jShell 命令
-
多版本兼容 jar 包(這個在處理向下兼容方面,非常好用)
-
語法改進:接口的私有方法
-
語法改進:UnderScore(下劃線)使用的限制
-
底層結構:String 存儲結構變更(這個很重要)
-
集合工廠方法:快速創建只讀集合
-
增強的 Stream API
-
全新的 HTTP 客戶端 API
-
其它特性
-
它的新特性來自于100于項JEP和40于項JSR
?
Java 10
2018年3月20日,Java 10 正式發布,這一次沒有跳票。它號稱有109項新特性,包含12個JEP。需要注意的是,本次Java10并不是Oracle的官方LTS版本,還是坐等java11的發布再考慮在生產中使用
特性列表
-
局部變量的類型推斷 var關鍵字
-
GC改進和內存管理 并行全垃圾回收器 G1
-
垃圾回收器接口
-
線程-局部變量管控
-
合并 JDK 多個代碼倉庫到一個單獨的儲存庫中
-
新增API:ByteArrayOutputStream
-
新增API:List、Map、Set
-
新增API:java.util.Properties
-
新增API: Collectors收集器
-
其它特性
1、局部變量的類型推斷 var關鍵字
這個新功能將為Java增加一些語法糖 - 簡化它并改善開發者體驗。新的語法將減少與編寫Java相關的冗長度,同時保持對靜態類型安全性的承諾。
這可能是Java10給開發者帶來的最大的一個新特性。下面主要看例子:
public?static?void?main(String[]?args)?{var?list?=?new?ArrayList<String>();list.add("hello,world!");System.out.println(list);}這是最平常的使用。注意賦值語句右邊,最好寫上泛型類型,否則會有如下情況:
public?static?void?main(String[]?args)?{var?list?=?new?ArrayList<>();list.add("hello,world!");list.add(1);list.add(1.01);System.out.println(list);}list什么都可以裝,非常的不安全了。和js等語言不同的是,畢竟Java還是強類型的語言,所以下面語句是編譯報錯的:
public?static?void?main(String[]?args)?{var?list?=?new?ArrayList<String>();list.add("hello,world!");System.out.println(list);list?=?new?ArrayList<Integer>();?//編譯報錯}注意:下面幾點使用限制
局部變量初始化
for循環內部索引變量
傳統的for循環聲明變量
下面這幾種情況,都是不能使用var的
方法參數
全局變量
構造函數參數
方法返回類型
字段
捕獲表達式(或任何其他類型的變量聲明)
2、GC改進和內存管理 并行全垃圾回收器 G1
JDK 10中有2個JEP專門用于改進當前的垃圾收集元素。
Java 10的第二個JEP是針對G1的并行完全GC(JEP 307),其重點在于通過完全GC并行來改善G1最壞情況的等待時間。G1是Java 9中的默認GC,并且此JEP的目標是使G1平行。
3、垃圾回收器接口
這不是讓開發者用來控制垃圾回收的接口;而是一個在 JVM 源代碼中的允許另外的垃圾回收器快速方便的集成的接口。
4、線程-局部變量管控
這是在 JVM 內部相當低級別的更改,現在將允許在不運行全局虛擬機安全點的情況下實現線程回調。這將使得停止單個線程變得可能和便宜,而不是只能啟用或停止所有線程。
5、合并 JDK 多個代碼倉庫到一個單獨的儲存庫中
在 JDK9 中,有 8 個倉庫: root、corba、hotspot、jaxp、jaxws、jdk、langtools 和 nashorn 。在 JDK10 中這些將被合并為一個,使得跨相互依賴的變更集的存儲庫運行 atomic commit (原子提交)成為可能。
6、新增API:ByteArrayOutputStream
String toString(Charset): 重載 toString(),通過使用指定的字符集解碼字節,將緩沖區的內容轉換為字符串。
7、新增API:List、Map、Set
這3個接口都增加了一個新的靜態方法,copyOf(Collection)。這些函數按照其迭代順序返回一個不可修改的列表、映射或包含給定集合的元素的集合。
8、新增API:java.util.Properties
增加了一個新的構造函數,它接受一個 int 參數。這將創建一個沒有默認值的空屬性列表,并且指定初始大小以容納指定的元素數量,而無需動態調整大小。還有一個新的重載的 replace 方法,接受三個 Object 參數并返回一個布爾值。只有在當前映射到指定值時,才會替換指定鍵的條目。
9、新增API: Collectors收集器
toUnmodifiableList():
toUnmodifiableSet():
toUnmodifiableMap(Function, Function):
toUnmodifiableMap(Function, Function, BinaryOperator):
這四個新方法都返回 Collectors ,將輸入元素聚集到適當的不可修改的集合中。
10、其它特性
線程本地握手(JEP 312)
其他Unicode語言 - 標記擴展(JEP 314)
基于Java的實驗性JIT編譯器
根證書頒發認證(CA)
刪除工具javah(JEP 313)
從JDK中移除了javah工具,這個很簡單并且很重要。
最后
JDK10的升級幅度其實主要還是以優化為主,并沒有帶來太多對使用者驚喜的特性。所以建議廣大開發者還是坐等Java11吧,預計2018年9月份就會到來,最重要的是它是LTS版本哦,所以是可以運用在生產上的。
?
Java 11
2018年9月26日,Oracle 官方宣布 Java 11 正式發布。這是 Java 大版本周期變化后的第一個長期支持版本(LTS版本,Long-Term-Support,持續支持到2026年9月),非常值得關注。
Java11 帶來了 ZGC、Http Client 等重要特性,一共包含 17 個 JEP(JDK Enhancement Proposals,JDK 增強提案)。
特性列表
官方新特性:
本文針對于讀者對關心、也是最實用的八大新特性做出一些講解
-
本地變量類型推斷
-
字符串加強
-
集合加強
-
Stream 加強
-
Optional 加強
-
InputStream 加強
-
HTTP Client API
-
化繁為簡,一個命令編譯運行源代碼
3、集合加強
自 Java 9 開始,Jdk 里面為集合(List/ Set/ Map)都添加了 of 和 copyOf 方法,它們兩個都用來創建不可變的集合,來看下它們的使用和區別。
示例1:
示例2:
var?list?=?new?ArrayList<String>(); var?copy?=?List.copyOf(list); System.out.println(list?==?copy);?//?false示例1和2代碼差不多,為什么一個為true,一個為false?
來看下它們的源碼:
可以看出 copyOf 方法會先判斷來源集合是不是 AbstractImmutableList 類型的,如果是,就直接返回,如果不是,則調用 of 創建一個新的集合。
示例2因為用的 new 創建的集合,不屬于不可變 AbstractImmutableList 類的子類,所以 copyOf 方法又創建了一個新的實例,所以為false.
注意:使用of和copyOf創建的集合為不可變集合,不能進行添加、刪除、替換、排序等操作,不然會報 java.lang.UnsupportedOperationException 異常。
上面演示了 List 的 of 和 copyOf 方法,Set 和 Map 接口都有。
public?static?void?main(String[]?args)?{Set<String>?names?=?Set.of("Fred",?"Wilma",?"Barney",?"Betty");//JDK11之前我們只能這么寫System.out.println(Arrays.toString(names.toArray(new?String[names.size()])));//JDK11之后??可以直接這么寫了System.out.println(Arrays.toString(names.toArray(size?->?new?String[size])));System.out.println(Arrays.toString(names.toArray(String[]::new)));}Collection.toArray(IntFunction)
在java.util.Collection接口中添加了一個新的默認方法toArray(IntFunction)。此方法允許將集合的元素傳輸到新創建的所需運行時類型的數組。
4、Stream 加強
Stream 是 Java 8 中的新特性,Java 9 開始對 Stream 增加了以下 4 個新方法。
- 增加單個參數構造方法,可為null
源碼可看看:
/***?@since?9*/public?static<T>?Stream<T>?ofNullable(T?t)?{return?t?==?null???Stream.empty():?StreamSupport.stream(new?Streams.StreamBuilderImpl<>(t),?false);}- 增加 takeWhile 和 dropWhile 方法
takeWhile表示從開始計算,當 n < 3 時就截止。
Stream.of(1,?2,?3,?2,?1) .dropWhile(n?->?n?<?3) .collect(Collectors.toList());?//?[3,?2,?1]- iterate重載
這個 iterate 方法的新重載方法,可以讓你提供一個 Predicate (判斷條件)來指定什么時候結束迭代。
public?static?void?main(String[]?args)?{//?這構造的是無限流??JDK8開始Stream.iterate(0,?(x)?->?x?+?1);//?這構造的是小于10就結束的流??JDK9開始Stream.iterate(0,?x?->?x?<?10,?x?->?x?+?1);}5、Optional 加強
Opthonal 也增加了幾個非常酷的方法,現在可以很方便的將一個 Optional 轉換成一個 Stream, 或者當一個空 Optional 時給它一個替代的。
Optional.of("javastack").orElseThrow();?//?javastack Optional.of("javastack").stream().count();?//?1 Optional.ofNullable(null) .or(()?->?Optional.of("javastack")) .get();?//?javastacor方法和stream方法顯然都是新增的
6、InputStream 加強
InputStream 終于有了一個非常有用的方法:transferTo,可以用來將數據直接傳輸到 OutputStream,這是在處理原始數據流時非常常見的一種用法,如下示例。
var?classLoader?=?ClassLoader.getSystemClassLoader(); var?inputStream?=?classLoader.getResourceAsStream("javastack.txt"); var?javastack?=?File.createTempFile("javastack2",?"txt"); try?(var?outputStream?=?new?FileOutputStream(javastack))?{inputStream.transferTo(outputStream); }7、HTTP Client API(重磅)
在java9及10被標記incubator的模塊jdk.incubator.httpclient,在java11被標記為正式,改為java.net.http模塊。
這是 Java 9 開始引入的一個處理 HTTP 請求的的孵化 HTTP Client API,該 API 支持同步和異步,而在 Java 11 中已經為正式可用狀態,你可以在 java.net 包中找到這個 API。
來看一下 HTTP Client 的用法:
上面的 .GET() 可以省略,默認請求方式為 Get!
更多使用示例可以看這個 API,后續有機會再做演示。
現在 Java 自帶了這個 HTTP Client API,我們以后還有必要用 Apache 的 HttpClient 工具包嗎?我覺得沒啥必要了
8、化繁為簡,一個命令編譯運行源代碼
看下面的代碼。
//?編譯 javac?Javastack.java //?運行 java?Javastack在我們的認知里面,要運行一個 Java 源代碼必須先編譯,再運行,兩步執行動作。而在未來的 Java 11 版本中,通過一個 java 命令就直接搞定了,如以下所示。
java?Javastack.java移除項
移除了com.sun.awt.AWTUtilities
移除了sun.misc.Unsafe.defineClass,
使用 java.lang.invoke.MethodHandles.Lookup.defineClass來替代
移除了Thread.destroy()以及 Thread.stop(Throwable)方法移除了
sun.nio.ch.disableSystemWideOverlappingFileLockCheck、sun.locale.formatasdefault屬性
移除了jdk.snmp模塊
移除了javafx,openjdk估計是從java10版本就移除了,oracle jdk10還尚未移除javafx,而java11版本則oracle的jdk版本也移除了javafx
移除了Java Mission Control,從JDK中移除之后,需要自己單獨下載
移除了這些Root Certificates :Baltimore Cybertrust Code Signing CA,SECOM ,AOL and Swisscom
廢棄項
廢棄了Nashorn JavaScript Engine
廢棄了-XX+AggressiveOpts選項
-XX:+UnlockCommercialFeatures以及
-XX:+LogCommercialFeatures選項也不- 再需要
廢棄了Pack200工具及其API
說到最后
java11是java改為6個月發布一版的策略之后的第一個LTS(Long-Term Support)版本(oracle版本才有LTS),這個版本最主要的特性是:在模塊方面移除Java EE以及CORBA模塊,在JVM方面引入了實驗性的ZGC,在API方面正式提供了HttpClient類。
從java11版本開始,不再單獨發布JRE或者Server JRE版本了,有需要的可以自己通過jlink去定制runtime image
備注:ZGC作為實驗性功能包含在內。要啟用它,因此需要將-XX:+ UnlockExperimentalVMOptions選項與-XX:+ UseZGC選項結合使用。
ZGC的這個實驗版具有以下限制:
-
它僅適用于Linux / x64。
-
不支持使用壓縮的oops和/或壓縮的類點。默認情況下禁用-XX:+UseCompressedOops和-XX:+UseCompressedClassPointers選項。啟用它們將不起作用。
-
不支持類卸載。默認情況下禁用-XX:+ ClassUnloading和-XX:+ - - ClassUnloadingWithConcurrentMark選項。啟用它們將不起作用。
-
不支持將ZGC與Graal結合使用。
總結
以上是生活随笔為你收集整理的Java 5~11各个版本新特性史上最全总结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JSON是什么,为什么这么流行?
- 下一篇: 弹幕,你知道是怎样练成的?