JavaSE 7 新特性介绍
一、概述
2010-12-06,JCP投票通過(guò)了J2SE 7(JSR336)和J2SE 8(JSR337)兩個(gè)版本的規(guī)范,之前大家比較關(guān)注的Lambda表達(dá)式和模塊化系統(tǒng)則被推遲到了8中。按照Oracle的進(jìn)度("Plan B"),計(jì)劃在2011年中推出Oracle JDK7,在2012年晚些時(shí)候推出JDK8。截至12月16日,JDK7的所有特性已經(jīng)完成,也就是說(shuō)最新的JDK7中已經(jīng)包括7中所有的特性。
額外提一下此次投票情況,如下。由于Apache與Sun/Oracle關(guān)于Java授權(quán)的爭(zhēng)端最終導(dǎo)致Apache宣布退出JCP。
二、特性列表
下面列出的是J2SE 7規(guī)范的參考實(shí)現(xiàn)Oracle JDK7的特性列表:
b)、添加URLClassLoader的關(guān)閉方法
c)、并發(fā)和集合的一些更新
b)、Locale enhancement
c)、user locale和 user-interface locale分離
b)、針對(duì)zip/jar的NIO.2文件系統(tǒng)提供者
c)、SCTP on Solaris
d)、SDP on Solaris or Linux
e)、使用windows vista IPv6協(xié)議棧
f)、支持TLS 1.2
b)、針對(duì)jdk 6u10中提供的新功能(半透明和不規(guī)則窗體,輕重量級(jí)組件的混合使用,改進(jìn)的AWT警告)創(chuàng)建新的平臺(tái)接口
c)、Nimbus L2F
d)、JXLayer 組件
三、部分特性詳述
1、動(dòng)態(tài)類(lèi)型語(yǔ)言支持(Invokedynamic)
在JDK中增加了一個(gè)invokeDynamic 字節(jié)碼指令和相關(guān)的APIs (JSR 292),用于在缺少靜態(tài)類(lèi)型信息的情況下,提高動(dòng)態(tài)語(yǔ)言在Java虛擬機(jī)上執(zhí)行方法調(diào)用的性能。
之前,在JVM中存在四種用于方法調(diào)用的字節(jié)碼指令:
Invokevirtual:調(diào)用實(shí)例方法,基于類(lèi)的分派。
invokeinterface:調(diào)用接口方法?
invokestatic:調(diào)用一個(gè)類(lèi)的靜態(tài)方法
invokespecial:調(diào)用實(shí)例方法。用于特別處理超類(lèi)方法,私有方法和實(shí)例初始化方法的調(diào)用。
新的invokedynamic指令在很多方面與invokevirtual類(lèi)似,但是它更少由字節(jié)碼的校驗(yàn)規(guī)則來(lái)約束,而是通過(guò)動(dòng)態(tài)類(lèi)型的檢查來(lái)保持VM的完整性。
Invokedynamic語(yǔ)法:
invokedynamic <method-specification> <n> ?
對(duì)于<method-specification>只需指定方法名稱(chēng),對(duì)描述符的唯一要求是它應(yīng)引用非空對(duì)象。
由于VM只知道方法名稱(chēng),對(duì)于返回類(lèi)型和參數(shù)類(lèi)型則是未知的,而VM需要鏈接并調(diào)用真實(shí)的方法,所以在JDK7中,提供了一套新的動(dòng)態(tài)類(lèi)型語(yǔ)言的鏈接機(jī)制——方法句柄(Method Handles),VM通過(guò)鏈接機(jī)制獲取所需真實(shí)的方法。鏈接機(jī)制的相關(guān)類(lèi)主要在java.dyn中。
詳細(xì)內(nèi)容參見(jiàn):Da Vinci Machine Project
?
2、語(yǔ)法上改進(jìn)
a)、自動(dòng)化的資源管理-ARM
語(yǔ)法規(guī)則:
try ( *ResourceDeclarations* ) *Block Catchesopt Finallyopt*?
其中*ResourceDeclarations*必須實(shí)現(xiàn)Closeable接口,可以為:
*LocalVariableDeclaration* *LocalVariableDeclaration* ; *ResourceDeclarations示例如下圖所示,后一個(gè)方法為采用ARM的實(shí)現(xiàn)。
public void copy(String src, String dest) throws IOException {InputStream in = new FileInputStream(src);try {OutputStream out = new FileOutputStream(dest);try {byte[] buf = new byte[8 * 1024];int n;while ((n = in.read(buf)) >= 0) {out.write(buf, 0, n);}} finally {out.close();}} finally {in.close();}}public void autoResMngCopy(String src, String dest) throws IOException { try (InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest)) { byte[] buf = new byte[8192]; int n; while ((n = in.read(buf)) >= 0) { out.write(buf, 0, n); } } } ?
一些說(shuō)明:
- JDK7中所有的Closeable對(duì)象都實(shí)現(xiàn)了AutoCloseable (public interface Closeable extends AutoCloseable)
- 資源實(shí)例必須實(shí)現(xiàn)AutoCloseable中的public void close()方法才可以
- JDK7中JDBC 4.1相關(guān)接口也會(huì)更新為AutoCloseable
- 編譯器會(huì)在代碼塊中嵌入變量跟蹤異常狀態(tài),同時(shí)通過(guò)一種新的機(jī)制來(lái)記錄隱藏異常
- 可以通過(guò)注解處理器來(lái)查找適合更新的已有代碼 [鏈接]
b)、泛型示例創(chuàng)建時(shí)類(lèi)型接口的改進(jìn)—Diamond(<>)
為了使java代碼清晰簡(jiǎn)短,用一個(gè)空的類(lèi)型參數(shù)<>,替換之前明確列出的類(lèi)型參數(shù)。例如
Map<String, List<String>> mapList = new HashMap<String, List<String>>();?
替換為:
Map<String, List<String>> mapList=new HashMap<>(); ?
使用場(chǎng)景:構(gòu)造對(duì)象,委派給變量,傳遞參數(shù)
c)、簡(jiǎn)化可變參數(shù)的方法調(diào)用
減少類(lèi)型安全性的警告信息,把在調(diào)用出現(xiàn)時(shí)的警告信息放到了方法的聲明處
變化前
方法聲明:
static <T> List<T> asList(T... elements) { ... } ?
?方法調(diào)用:
static List<Callable<String>> stringFactories() {Callable<String> a, b, c;...*// Warning: **"uses unchecked or unsafe operations"*return asList(a, b, c);} ??
變化后:
方法聲明:
*// Warning: **"enables unsafe generic array creation"*static List asList(T... elements) { ... }?
方法調(diào)用:
static List> stringFactories() {Callable a, b, c;...return asList(a, b, c);}?
d)、Switch支持字符串
private void caseStr(String s) {switch (s) {case "a":System.out.println("case:" + s);break;case "b":System.out.println("case:" + s);break;case "c":System.out.println("case:" + s);break;default:System.out.println("unknown string:" + s);}}?
e)、異常的多重捕捉和更加精確的重新拋出
void test(boolean b1, boolean b2) throws BException { try { if (b1) { throw new AException(); } else if (b2) { throw new BException(); } else { throw new CException(); } } catch (final AException|CException e){ } }?
f)、改進(jìn)的整數(shù)值符
public void testUnderscore() { int a = 12345, b = 1_2_3_4_5, c = 1_23_4_5; int a1 = 0x12345, b1 = 0x1_2_3_4_5, c1 = 0x1_23_4_5; int a2 = 0b10101, b2 = 0b1_0_1_0_1, c2 = 0b1_01_0_1; assertTrue(a == b); assertTrue(c == b); assertTrue(a1 == b1); assertTrue(c1 == b1); assertTrue(a2 == b2); assertTrue(c2 == b2); } ?
3、Fork/Join框架
隨著多核技術(shù)的發(fā)展,為了充分利用硬件資源,需要應(yīng)用程序在更細(xì)的粒度上實(shí)現(xiàn)并發(fā)控制,為此,Java 7中引入了fork/join并發(fā)框架。其采用了分而治之(divide-and-conquer)的思想:
對(duì)問(wèn)題進(jìn)行評(píng)估,確定其大小是否更適合使用順序解決方案;通常,可通過(guò)將問(wèn)題大小與某個(gè)閾值進(jìn)行比較完成。如果問(wèn)題大到需要并行分解,算法會(huì)遞歸地將它分成多個(gè)子問(wèn)題,直到每個(gè)子問(wèn)題都足夠小,以至于可以高效地串行化解決它們;然后把這些問(wèn)題放入隊(duì)列中等待處理(fork步驟),接下來(lái)等待所有子問(wèn)題的結(jié)果(join步驟),把多個(gè)結(jié)果合并到一起。用于選擇順序和并行執(zhí)行方法的理想閾值是協(xié)調(diào)并行任務(wù)的成本。
偽代碼描述如下:
Result solve(Problem problem) { if (problem is small) directly solve problem else { split problem into independent parts fork new subtasks to solve each part join all subtasks compose result from subresults } }?
Fork/Join主要類(lèi)的結(jié)構(gòu)圖如下,其中ForkJoinTask的幾個(gè)子類(lèi)分別為:
RecursiveAction:無(wú)返回結(jié)果,不需要進(jìn)行合并
RecursiveTask:帶有返回值
AsyncAction/LinkedAsyncAction: 使用?finish()?方法顯式中止
CyclicAction:可使用 TaskBarrier 為每個(gè)任務(wù)設(shè)置不同中止條件
一些說(shuō)明:
- Fork/Join框架使用與可用核數(shù)相匹配的適當(dāng)大小的線程池,以減少頻繁交換的開(kāi)銷(xiāo)。
- 為避免線程空閑,框架中采用了一種叫工作竊取(work stealing)的技術(shù),可以使空閑線程從一個(gè)執(zhí)行較慢的線程中竊取等待其處理的工作,其主要是通過(guò)雙端隊(duì)列(Deque)來(lái)實(shí)現(xiàn)。
- Fork/Join框架是針對(duì)大的,多核系統(tǒng)采取的并發(fā)框架,如果少于4個(gè)核心的話,效率并不會(huì)有太多的提升。
- 一些額外的新特性,如ThreadLocal偽隨機(jī)數(shù)產(chǎn)生器—ThreadLocalRandom;靈活可復(fù)用的同步barrier—Phaser等。
4、新的I/O APIs(NIO.2):
已有I/O接口的問(wèn)題:
- 需要一個(gè)文件系統(tǒng)的接口而不是File類(lèi)
- 文件名稱(chēng)的處理方式不是跨平臺(tái)的
- 不支持有效的文件屬性訪問(wèn)
- 不支持文件系統(tǒng)的高級(jí)特性,如符號(hào)鏈接
- 許多方法只返回true/false或者error而不是有效的異常信息
- 非阻塞I/O機(jī)制應(yīng)用到Socket中,但沒(méi)有用到文件系統(tǒng)操作中;另外,下一代網(wǎng)絡(luò)控制器和操作系統(tǒng)會(huì)對(duì)異步I/O提供更好的支持
NIO.2中的主要功能:
- 支持大量訪問(wèn)文件屬性,避免暴露專(zhuān)有API的文件系統(tǒng)接口以及一個(gè)實(shí)現(xiàn)可拔插的文件系統(tǒng)服務(wù)提供者接口
- 在Socket和文件的操作上,支持異步的非阻塞的I/O操作。
- 完成Socket-channel功能(JSR-51),包括附件的對(duì)綁定,配置,多播的支持。
基本對(duì)象:
FileSystem:文件系統(tǒng)訪問(wèn)接口,是訪問(wèn)文件的對(duì)象(Path,WatchService)生成工廠
FileRef:文件(文件或目錄)引用
Path:提供獨(dú)立路徑
FileStore:文件存儲(chǔ)對(duì)象,可能是存儲(chǔ)池,設(shè)備,分區(qū)等
FileSystemProvider:文件系統(tǒng)的服務(wù)提供者,是FileSystem,FileRef和FileChanel的創(chuàng)建工廠。
WatchService:監(jiān)聽(tīng)Watchable對(duì)象(Path)的變化和相關(guān)事件。
FileVisitor:文件訪問(wèn)者,實(shí)現(xiàn)類(lèi)通過(guò)調(diào)用Files. walkFileTree來(lái)對(duì)文件樹(shù)遍歷
PathMatcher:判斷給定路徑是否符合matcher的模式
UserPrincipalLookupService:提供通過(guò)名稱(chēng)來(lái)查找用戶和組的主體(UserPrincipal),用來(lái)判斷對(duì)文件的訪問(wèn)權(quán)限。
主要關(guān)系結(jié)構(gòu)圖如下:
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
?
新舊APIs的對(duì)應(yīng)關(guān)系:
| java.io.File | java.nio.file |
| java.io.File? | java.nio.file.Path? |
| java.io.RandomAccessFile? | SeekableByteChannel? |
| File.canRead,?canWrite,?canExecute? | Path.checkAccess?.?on Unix,?Attributes? is used to check the permissions.? |
| The?File?methods:?isDirectory,isFile,?setExecutable,?setReadable,setReadOnly,?lastModified,setLastModified,?length,?setWritable? | replaced by java.nio.file.attributes?package, which reads the attributes in a more efficient bulk operation. |
| new File(parent, "newfile")? | parent.resolve("newfile")? |
| File.renameTo? | Path.moveTo? |
| File.delete? | Path.delete?or?Path.delete(boolean)? |
| File.createNewFile? | Path.createFile? |
| File.deleteOnExit? | Specified in the?createFile?method. |
| File.createTempFile? | Using the?DELETE_ON_CLOSE?option with the createFile?method. An easy way:? Path tmpFile = File.createTempFile("blah",null).toPath(); |
| File.exists? | Path.exists?and?Path.notExists? |
| File.compareTo?and?equals? | Path.compareTo?and?equals |
| File.getAbsolutePath?andgetAbsoluteFile? | Path.toAbsolutePath? |
| File.getCanonicalPath?andgetCanonicalFile? | Path.toRealPath?or?normalize? |
| File.toURI? | Path.toURI? |
| File.isHidden? | Path.isHidden? |
| File.list?and?listFiles? | Path.newDirectoryStream? |
| File.mkdir?and?mkdirs | Path.createDirectory? |
| File.listRoots? | FileSystem.getRootDirectories? |
| File.getTotalSpace,?File.getFreeSpace,File.getUsableSpace? | Attributes.readFileStoreSpaceAttributes? |
異步I/O:
異步IO實(shí)現(xiàn)的目的主要基于兩點(diǎn):統(tǒng)一Socket和文件系統(tǒng)的異步IO APIs;充分利用操作系統(tǒng)提供的IO機(jī)制。
基礎(chǔ)類(lèi):
- AsynchronousChannel – 標(biāo)識(shí)一個(gè)支持異步I/O的通道。
- AsynchronousByteChannel – 標(biāo)識(shí)一個(gè)支持讀寫(xiě)字節(jié)的異步通道,這個(gè)接口擴(kuò)展了AsynchronousChannel。
- AsynchronousDatagramChannel – 標(biāo)識(shí)一個(gè)面向數(shù)據(jù)報(bào)套接字異步通道,這個(gè)類(lèi)實(shí)現(xiàn)了AsynchronousByteChannel。
- AsynchronousFileChannel – 標(biāo)識(shí)一個(gè)可讀,寫(xiě)和操作文件的異步通道,這個(gè)類(lèi)實(shí)現(xiàn)了AsynchronousChannel。
- AsynchronousServerSocketChannel – 標(biāo)識(shí)一個(gè)面向流監(jiān)聽(tīng)套接字的異步通道,這個(gè)類(lèi)實(shí)現(xiàn)了AsynchronousChannel。
- AsynchronousSocketChannel – 標(biāo)識(shí)一個(gè)面向流連接套接字的異步通道,這個(gè)類(lèi)實(shí)現(xiàn)了AsynchronousByteChannel。
- AsynchronousChannelGroup – 標(biāo)識(shí)一個(gè)用于資源共享的異步通道組。
兩種異步操作方式:
Future方式:初始化IO操作,返回java.util.concurrent.Future;在Future接口中定義檢測(cè)任務(wù)是否完成的方法。示例如下:
AsynchronousSocketChannel ch = AsynchronousSocketChannel.open();// initiate connection// wait for connection to be established or failure //Future result = ch.connect(remote);result.get();ByteBuffer buf = ...// initiate readFuture result = ch.read(buf);// do something// wait for read to completetry {int bytesRead = result.get();} catch (ExecutionExecption x) {// failed}?
CallBack方式:調(diào)用IO操作時(shí)指定CompletionHandler,其在IO操作完成或者失敗時(shí)調(diào)用。
示例如下:
ByteBuffer buf = ...// CompletionHandler invoked when read completesch.read(buffer, ..., new CompletionHandler() {public void completed(IoFuture result) {try {int bytesRead = result.getNow();} catch (IOException x) {// error handling}}}??
關(guān)于異步IO中線程調(diào)度及其管理,網(wǎng)上有很多詳細(xì)的討論,在此不表。
四、參考資料
1、JaveSE 7 JSR:http://jcp.org/en/jsr/detail?id=336
2、OpenJDK-JDK7:http://openjdk.java.net/projects/jdk7/
3、Mark Reinhold`s Blog:http://blogs.sun.com/mr/
4、Da Vinci Machine Project:http://openjdk.java.net/projects/mlvm/
5、Project Coin: http://openjdk.java.net/projects/coin/
6、Doug Lea:http://gee.cs.oswego.edu/dl/
7、Doug Lea:《A Java Fork/Join Framework》
8、IBM DW: http://www.ibm.com/developerworks/cn/java/j-lo-forkjoin/index.html
9、NIO2 Project: http://openjdk.java.net/projects/nio/
10、Tutorials: http://download.oracle.com/javase/tutorial/essential/io/fileio.html
總結(jié)
以上是生活随笔為你收集整理的JavaSE 7 新特性介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 夺命追击(Murderous Pursu
- 下一篇: 使用mybatis向数据库插入不进数据