Java的發(fā)展真的越來(lái)越快了,在Java9正式發(fā)布之前,我們可以使用它的SNAPSHOT版本,先來(lái)體驗(yàn)一下Java9有哪些新的特性,下面的清單來(lái)自于官方文檔,看著似乎很多,但是真正具有顛覆意義的其實(shí)就是ModuleSystem,其余很多主要是一些新的feature增加,還有一些功能的加強(qiáng),在本篇文章中,我們將介紹一下主要的幾個(gè),不會(huì)一一去說(shuō),資料也不多,所以我想說(shuō)也沒(méi)的說(shuō),另外Java8是我認(rèn)為迄今為止Java最大的一次變化,不光是特性的增加,更多的是編程風(fēng)格的轉(zhuǎn)變,
102:ProcessAPIUpdates
110:HTTP2Client
143:ImproveContendedLocking
158:UnifiedJVMLogging
165:CompilerControl
193:VariableHandles
197:SegmentedCodeCache
199:SmartJavaCompilation,PhaseTwo
200:TheModularJDK
201:ModularSourceCode
211:ElideDeprecationWarningsonImportStatements
212:ResolveLintandDoclintWarnings
213:MillingProjectCoin
214:RemoveGCCombinationsDeprecatedinJDK
8215:TieredAttributionforjavac
216:ProcessImportStatementsCorrectly
217:AnnotationsPipeline2.0
219:DatagramTransportLayerSecurity(DTLS)
220:ModularRun-TimeImages
221:SimplifiedDocletAPI
222:jshell:TheJavaShell(Read-Eval-PrintLoop)
223:NewVersion-StringScheme
224:HTML5Javadoc
225:JavadocSearch
226:UTF-8PropertyFiles
227:Unicode7.0
228:AddMoreDiagnosticCommands
229:CreatePKCS12KeystoresbyDefault
231:RemoveLaunch-TimeJREVersionSelection
232:ImproveSecureApplicationPerformance
233:GenerateRun-TimeCompilerTestsAutomatically
235:TestClass-FileAttributesGeneratedbyjavac
236:ParserAPIforNashorn
237:Linux/AArch64Port
238:Multi-ReleaseJARFiles
240:RemovetheJVMTIhprofAgent
241:RemovethejhatTool
243:Java-LevelJVMCompilerInterface
244:TLSApplication-LayerProtocolNegotiationExtension
245:ValidateJVMCommand-LineFlagArguments
246:LeverageCPUInstructionsforGHASHandRSA
247:CompileforOlderPlatformVersions2
48:MakeG1theDefaultGarbageCollector
249:OCSPStaplingforTLS250:StoreInternedStringsinCDSArchives
251:Multi-ResolutionImages
252:UseCLDRLocaleDatabyDefault
253:PrepareJavaFXUIControls&CSSAPIsforModularization
254:CompactStrings
255:MergeSelectedXerces2.11.0UpdatesintoJAXP
256:BeanInfoAnnotations
257:UpdateJavaFX/MediatoNewerVersionofGStreamer
258:HarfBuzzFont-LayoutEngine
259:Stack-WalkingAPI260:EncapsulateMostInternalAPIs
261:ModuleSystem
262:TIFFImageI/O
263:HiDPIGraphicsonWindowsandLinux
264:PlatformLoggingAPIandService
265:MarlinGraphicsRenderer
266:MoreConcurrencyUpdates
267:Unicode8.0268:XMLCatalogs
269:ConvenienceFactoryMethodsforCollections
270:ReservedStackAreasforCriticalSections
271:UnifiedGCLogging
272:Platform-SpecificDesktopFeatures
273:DRBG-BasedSecureRandomImplementations
274:EnhancedMethodHandles
275:ModularJavaApplicationPackaging
276:DynamicLinkingofLanguage-DefinedObjectModels
277:EnhancedDeprecation
278:AdditionalTestsforHumongousObjectsinG
1279:ImproveTest-FailureTroubleshooting
280:IndifyStringConcatenation
281:HotSpotC++Unit-TestFramework
282:jlink:TheJavaLinker
283:EnableGTK3onLinux
284:NewHotSpotBuildSystem
285:Spin-WaitHints287:SHA-3HashAlgorithms
288:DisableSHA-1Certificates
289:DeprecatetheAppletAPI
290:FilterIncomingSerializationData
292:ImplementSelectedECMAScript6FeaturesinNashorn
294:Linux/s
390xPort295:Ahead-of-TimeCompilation
1.ModularSystem–JigsawProject
該特性是Java9最大的一個(gè)特性,Java9起初的代號(hào)就叫Jigsaw,最近被更改為Modularity,Modularity提供了類(lèi)似于OSGI框架的功能,模塊之間存在相互的依賴(lài)關(guān)系,可以導(dǎo)出一個(gè)公共的API,并且隱藏實(shí)現(xiàn)的細(xì)節(jié),Java提供該功能的主要的動(dòng)機(jī)在于,減少內(nèi)存的開(kāi)銷(xiāo),我們大家都知道,在JVM啟動(dòng)的時(shí)候,至少會(huì)有30~60MB的內(nèi)存加載,主要原因是JVM需要加載rt.jar,不管其中的類(lèi)是否被classloader加載,第一步整個(gè)jar都會(huì)被JVM加載到內(nèi)存當(dāng)中去,模塊化可以根據(jù)模塊的需要加載程序運(yùn)行需要的class,那么JVM是如何知道需要加載那些class的呢?這就是在Java9中引入的一個(gè)新的文件module.java我們大致來(lái)看一下一個(gè)例子(module-info.java)
[java]viewplaincopyprint?- modulecom.baeldung.java9.modules.car{
- requirescom.baeldung.java9.modules.engines;
- exportscom.baeldung.java9.modules.car.handling;
- }
關(guān)于更多Java9模塊編程的內(nèi)容請(qǐng)參考一本書(shū):《Java9Modularity》里面講的比較詳細(xì),介紹了當(dāng)前Java對(duì)jar之間以來(lái)的管理是多么的混亂,引入modularity之后的改變會(huì)是很明顯的差別。
2.ANewHttpClient
就目前而言,JDK提供的Http訪(fǎng)問(wèn)功能,幾乎都需要依賴(lài)于HttpURLConnection,但是這個(gè)類(lèi)大家在寫(xiě)代碼的時(shí)候很少使用,我們一般都會(huì)選擇Apache的HttpClient,此次在Java9的版本中引入了一個(gè)新的package:java.net.http,里面提供了對(duì)Http訪(fǎng)問(wèn)很好的支持,不僅支持Http1.1而且還支持HTTP2,以及WebSocket,據(jù)說(shuō)性能可以超過(guò)ApacheHttpClient,Netty,Jetty,簡(jiǎn)單的來(lái)看一個(gè)代碼片段
[java]viewplaincopyprint?- URIhttpURI=newURI("http://www.94jiankang.com");
- HttpRequestrequest=HttpRequest.create(httpURI).GET();
- HttpResponseresponse=request.response();
- StringresponseBody=response.body(HttpResponse.asString());
3.ProcessAPIEnhance
在Java很早的版本中,提供了Process這樣的API可以獲得進(jìn)程的一些信息,包括runtime,甚至是用它來(lái)執(zhí)行當(dāng)前主機(jī)的一些命令,但是請(qǐng)大家思考一個(gè)問(wèn)題,你如何獲得你當(dāng)前Java運(yùn)行程序的PID?很顯然通過(guò)Process是無(wú)法獲得的,需要借助于JMX才能得到,但是在這一次的增強(qiáng)中,你將會(huì)很輕松的得到這樣的信息,我們來(lái)看一個(gè)簡(jiǎn)單的例子
[java]viewplaincopyprint?- ProcessHandleself=ProcessHandle.current();
- longPID=self.getPid();
- ProcessHandle.InfoprocInfo=self.info();
- Optional<String[]>args=procInfo.arguments();
- Optional<String>cmd=procInfo.commandLine();
- Optional<Instant>startTime=procInfo.startInstant();
- Optional<Duration>cpuUsage=procInfo.totalCpuDuration();
上面有大量的Optional,這是Java8中的API,同樣在Java9中對(duì)其進(jìn)行了增強(qiáng),本人在Java8實(shí)戰(zhàn)視頻中對(duì)OptionalAPI進(jìn)行了源碼級(jí)別的剖析,感興趣的一定要去看看。
已經(jīng)獲取到了JVM的進(jìn)程,我們?cè)撊绾螌⒃撨M(jìn)程優(yōu)雅的停掉呢?下面的代碼給出了答案
[java]viewplaincopyprint?- childProc=ProcessHandle.current().children();
- childProc.forEach(procHandle->{
- assertTrue("Couldnotkillprocess"+procHandle.getPid(),procHandle.destroy());
- });
通過(guò)上面的一小段代碼,我們也發(fā)現(xiàn)了Java9對(duì)斷言機(jī)制同樣增加了一些增強(qiáng),多說(shuō)一些題外話(huà),我們目前的系統(tǒng)中運(yùn)行一個(gè)嚴(yán)重依賴(lài)于HivebeelineServer的程序,beelineserver不是很穩(wěn)定,經(jīng)常出現(xiàn)卡頓,甚至假死,假死后也不回復(fù)的問(wèn)題,這樣就導(dǎo)致我們的程序也會(huì)出現(xiàn)卡頓,如果運(yùn)維人員不對(duì)其進(jìn)行清理,系統(tǒng)運(yùn)行幾個(gè)月之后會(huì)發(fā)現(xiàn)很多僵尸進(jìn)程,于是增加一個(gè)獲取當(dāng)前JVMPID的功能,然后判斷到超過(guò)給定的時(shí)間對(duì)其進(jìn)行主動(dòng)殺死,完全是程序內(nèi)部的行為,但是獲取PID就必須借助于JMX的動(dòng)作,另外殺死它也必須借助于操作系統(tǒng)的命令,諸如kill這樣的命令,顯得非常的麻煩,但是Java9的方式明顯要優(yōu)雅方便許多。
4.Try-With-Resources的改變
我們都知道,Try-With-Resources是從JDK7中引入的一項(xiàng)重要特征,只要接口繼承了Closable就可以使用Try-With-Resources,減少finally語(yǔ)句塊的編寫(xiě),在Java9中會(huì)更加的方便這一特征
[java]viewplaincopyprint?- MyAutoCloseablemac=newMyAutoCloseable();
- try(mac){
- //dosomestuffwithmac
- }
- try(newMyAutoCloseable(){}.finalWrapper.finalCloseable){
- //dosomestuffwithfinalCloseable
- }catch(Exceptionex){}
我們的Closeable完全不用寫(xiě)在try()中。
5.DiamondOperatorExtension
[java]viewplaincopyprint?- FooClass<Integer>fc=newFooClass<>(1){//anonymousinnerclass
- };
- FooClass<?extendsInteger>fc0=newFooClass<>(1){
- //anonymousinnerclass
- };
- FooClass<?>fc1=newFooClass<>(1){//anonymousinnerclass
- };
6.InterfacePrivateMethod
[java]viewplaincopyprint?- interfaceInterfaceWithPrivateMethods{
- privatestaticStringstaticPrivate(){
- return"staticprivate";
- }
- privateStringinstancePrivate(){
- return"instanceprivate";
- }
- defaultvoidcheck(){
- Stringresult=staticPrivate();
- InterfaceWithPrivateMethodspvt=newInterfaceWithPrivateMethods(){
- //anonymousclass
- };
- result=pvt.instancePrivate();
- }
- }}
該特性完全是為了Java8中default方法和static方法服務(wù)的。
7.JShellCommandLineTool
在Java8出來(lái)的時(shí)候,很多人都喊著,這是要搶奪Scala等基于JVM動(dòng)態(tài)語(yǔ)言的市場(chǎng)啊,其中有人給出了一個(gè)Java做不到的方向,那就是Scala可以當(dāng)作腳本語(yǔ)言,Java可以么?很明顯在此之前Java不行,ta也不具備動(dòng)態(tài)性,但是此次Java9卻讓Java也可以像腳本語(yǔ)言一樣來(lái)運(yùn)行了,主要得益于JShell,我們來(lái)看一下這個(gè)演示
[java]viewplaincopyprint?- jdk-9\bin>jshell.exe
- WelcometoJShell--Version9
- Foranintroductiontype:/helpintro
- jshell>"Thisismylongstring.Iwantapartofit".substring(8,19);
- $5==>"mylongstring"
這是我們?cè)贘shell這個(gè)控制臺(tái)下運(yùn)行,我們?nèi)绾芜\(yùn)行腳本文件呢?
[java]viewplaincopyprint?- jshell>/savec:\develop\JShell_hello_world.txt
- jshell>/openc:\develop\JShell_hello_world.txt
- HelloJShell!
8.JCMDSub-Commands
記得在Java8中,放棄了Jhat這個(gè)命令,但是很快在Java9中增加了一些新的命令,比如我們要介紹到的jcmd,借助它你可以很好的看到類(lèi)之間的依賴(lài)關(guān)系
[java]viewplaincopyprint?- jdk-9\bin>jcmd14056VM.class_hierarchy-i-sjava.net.Socket
- 14056:
- java.lang.Object/null
- --java.net.Socket/null
- implementsjava.io.Closeable/null(declaredintf)
- implementsjava.lang.AutoCloseable/null(inheritedintf)
- --org.eclipse.ecf.internal.provider.filetransfer.httpclient4.CloseMonitoringSocket
- implementsjava.lang.AutoCloseable/null(inheritedintf)
- implementsjava.io.Closeable/null(inheritedintf)
- --javax.net.ssl.SSLSocket/null
- implementsjava.lang.AutoCloseable/null(inheritedintf)
- implementsjava.io.Closeable/null(inheritedintf)
9.Мulti-ResolutionImageAPI
接口java.awt.image.MultiResolutionImage封裝了一系列的不同分辨率圖像到一個(gè)單獨(dú)對(duì)象的API,我么可以根據(jù)給定的DPI矩陣獲取resolution-specific,看一下下面的代碼片段
[java]viewplaincopyprint?- BufferedImage[]resolutionVariants=....
- MultiResolutionImagebmrImage
- =newBaseMultiResolutionImage(baseIndex,resolutionVariants);
- ImagetestRVImage=bmrImage.getResolutionVariant(16,16);
- assertSame("Imagesshouldbethesame",testRVImage,resolutionVariants[3]);
關(guān)于AWT的東西,本人幾乎不怎么接觸,如果有用到的朋友,等JDK9出來(lái)之后,自己體會(huì)使用一下吧。
10.VariableHandles
很早之前就傳言Java會(huì)將unsafe這一個(gè)類(lèi)屏蔽掉,不給大家使用,這次看他的官方文檔,貌似所有已sun開(kāi)頭的包都將不能在application中使用,但是java9提供了新的API供大家使用。
在JDK9中提供了一個(gè)新的包,叫做java.lang.invoke里面有一系列很重要的類(lèi)比如VarHandler和MethodHandles,提供了類(lèi)似于原子操作以及Unsafe操作的功能。
11.Publish-SubscribeFramework
在新版的JDK9中提供了消息發(fā)布訂閱的框架,該框架主要是由Flow這個(gè)類(lèi)提供的,他同樣會(huì)在java.util.concurrent中出現(xiàn),并且提供了Reactive編程模式。
12.UnifiedJVMLogging
該特性為JVM的所有組件引入了一個(gè)通用的日志系統(tǒng),提供了JVM日志的基礎(chǔ)設(shè)施,你可以不用專(zhuān)門(mén)為了打印某些日志而添加一些專(zhuān)門(mén)的標(biāo)簽,只需要使用統(tǒng)一的log指令即可,比如:
[java]viewplaincopyprint?- java-Xlog:gc=debug:file=gc.txt:none...
- jcmd9615VM.logoutput=gc_logswhat=gc
13.ImmutableSet
其實(shí)在Java的早期版本中就已經(jīng)有這樣的功能了,比如Collections.xxx就可以將某個(gè)collection封裝成不可變,但是此次的Java9版本將其加到了對(duì)應(yīng)的Set和List中,并且有一個(gè)專(zhuān)門(mén)的新包用來(lái)存放這些具體的實(shí)現(xiàn)java.util.ImmutableCollections,這一個(gè)特性和Scala真的如出一轍。
[java]viewplaincopyprint?- Set<String>strKeySet=Set.of("key1","key2","key3");
14.OptionalToStream
對(duì)Option提供了stream功能,關(guān)于Optional的用法,我在我的教程中講的非常詳細(xì),如果你還沒(méi)有掌握,抓緊啊
[java]viewplaincopyprint?- List<String>filteredList=listOfOptionals.stream()
- .flatMap(Optional::stream)
- .collect(Collectors.toList());