摘自: http://yanguz123.iteye.com/blog/1934766
Jdk1.7的新特性:
1,switch中可以使用字串
Java代碼:
String s = "test";
switch (s) {
case "test" :
System.out.println("test");
case "test1" :
System.out.println("test1");
break ;
default :
System.out.println("break");
break ;
}
2,"<>"這個玩意兒的運用List<String> tempList = new ArrayList<>(); 即泛型實例化類型自動推斷。
3. 語法上支持集合,而不一定是數組
Java代碼:
final List<Integer> piDigits = [ 1,2,3,4,5,8 ];
4. 新增一些取環境信息的工具方法
Java代碼:
File System.getJavaIoTempDir() // IO臨時文件夾
File System.getJavaHomeDir() // JRE的安裝目錄
File System.getUserHomeDir() // 當前用戶目錄
File System.getUserDir() // 啟動java進程時所在的目錄
.......
5. Boolean類型反轉,空指針安全,參與位運算
Java代碼:
Boolean Booleans.negate(Boolean booleanObj)
True => False , False => True, Null => Null
boolean Booleans.and(boolean[] array)
boolean Booleans.or(boolean[] array)
boolean Booleans.xor(boolean[] array)
boolean Booleans.and(Boolean[] array)
boolean Booleans.or(Boolean[] array)
boolean Booleans.xor(Boolean[] array)
6. 兩個char間的equals
Java代碼:
boolean Character.equalsIgnoreCase(char ch1, char ch2)
7,安全的加減乘除
Java代碼:
int Math.safeToInt(long value)
int Math.safeNegate(int value)
long Math.safeSubtract(long value1, int value2)
long Math.safeSubtract(long value1, long value2)
int Math.safeMultiply(int value1, int value2)
long Math.safeMultiply(long value1, int value2)
long Math.safeMultiply(long value1, long value2)
long Math.safeNegate(long value)
int Math.safeAdd(int value1, int value2)
long Math.safeAdd(long value1, int value2)
long Math.safeAdd(long value1, long value2)
int Math.safeSubtract(int value1, int value2)
首先是模塊化特性:現在的 Java7也是采用了模塊的划分方式來提速,一些不是必須的模塊並沒有下載和安裝,因此在使用全新的Java7的虛擬機的時候會發現真的很快,當虛擬機需要用到某些功能的時候,再下載和啟用相應的模塊,這樣使得最初需要下載的虛擬機大小得到了有效的控制。同時對啟動速度也有了很大的改善。如果你對 OpenJDK的架構比較熟悉,你甚至可以定制JDK的模塊。
其次是多語言支持:這里的多語言不是指中文英文之類的語言,而是說Java7的虛擬機對多種動態程序語言增加了支持,比如:Rubby、 Python等等。對這些動態語言的支持極大地擴展了Java虛擬機的能力。對於那些熟悉這些動態語言的程序員而言,在使用Java虛擬機的過程中同樣可以使用它們熟悉的語言進行功能的編寫,而這些語言是跑在功能強大的JVM之上的。
再有是開發者的開發效率得到了改善:Java7通過多種特性來增強開發效率。比如對語言本身做了一些細小的改變來簡化程序的編寫,在多線程並發與控制方面:輕量級的分離與合並框架,一個支持並發訪問的HashMap等等。通過注解增強程序的靜態檢查。提供了一些新的API用於文件系統的訪問、異步的輸入輸出操作、Socket通道的配置與綁定、多點數據包的傳送等等。
最后是執行效率的提高,也是給人感覺最真切體驗的特性:壓縮了64位的對象指針,Java7通過對對象指針由64位壓縮到與32位指針相匹配的技術使得內存和內存帶塊的消耗得到了很大的降低因而提高了執行效率。此外還提供了新的垃圾回收機制(G1)來降低垃圾回收的負載和增強垃圾回收的效果。G1垃圾回收機制擁有更低的暫停率和更好的可預測性。
jdk1.7新特性
1 對集合類的語言支持;
2 自動資源管理;
3 改進的通用實例創建類型推斷;
4 數字字面量下划線支持;
5 switch中使用string;
6 二進制字面量;
7 簡化可變參數方法調用;
8 新增一些取環境信息的工具方法;
9 Boolean類型反轉,空指針安全,參與位運算;
10 兩個char間的equals;
11 安全的加減乘除;
12 map集合支持並發請求 ,且可以寫成 Map map = {name:"xxx",age:18};
下面我們來仔細看一下這12個新功能:
1 對集合類的語言支持
Java將包含對創建集合類的第一類語言支持。這意味着集合類的創建可以像Ruby和Perl那樣了。
創建List / Set / Map 時寫法更簡單了。
List< String> list = ["item"];
String item = list[0];
Set< String > set = {"item"};
Map< String,Integer > map = {"key" : 1};
int value = map["key"];
原本需要這樣:
List<String> list = new ArrayList<String>();
list.add("item");
String item = list.get(0);
Set<String> set = new HashSet<String>();
set.add("item");
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("key", 1);
int value = map.get("key");
現在你可以這樣:
List<String> list = ["item"];
String item = list[0];
Set<String> set = {"item"};
Map<String, Integer> map = {"key" : 1};
int value = map["key"];
這些集合是不可變的。
2 自動資源管理
Java中某些資源是需要手動關閉的,如InputStream,Writes,Sockets,Sql classes等。這個新的語言特性允許try語句本身申請更多的資源,
這些資源作用於try代碼塊,並自動關閉。
這個:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
} finally {
br.close();
}
變成了這個:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
你可以定義關閉多個資源:
try (
InputStream in = new FileInputStream(src);
OutputStream out = new FileOutputStream(dest))
{
// code
}
為了支持這個行為,所有可關閉的類將被修改為可以實現一個Closable(可關閉的)接口。
3 增強的對通用實例創建(diamond)的類型推斷
類型推斷是一個特殊的煩惱,下面的代碼:
Map<String, List<String>> anagrams = new HashMap<String, List<String>>();
通過類型推斷后變成:
Map<String, List<String>> anagrams = new HashMap<>();
這個<>被叫做diamond(鑽石)運算符,這個運算符從引用的聲明中推斷類型。
4 數字字面量下划線支持
很長的數字可讀性不好,在Java 7中可以使用下划線分隔長int以及long了,如:
int one_million = 1_000_000;
運算時先去除下划線,如:1_1 * 10 = 110,120 – 1_0 = 110
5 switch中使用string
以前你在switch中只能使用number或enum。現在你可以使用string了:
String s = ...
switch(s) {
case "quux":
processQuux(s);
// fall-through
case "foo":
case "bar":
processFooOrBar(s);
break;
case "baz":
processBaz(s);
// fall-through
default:
processDefault(s);
break;
}
6 二進制字面量
由於繼承C語言,Java代碼在傳統上迫使程序員只能使用十進制,八進制或十六進制來表示數(numbers)。
由於很少的域是以bit導向的,這種限制可能導致錯誤。你現在可以使用0b前綴創建二進制字面量:
int binary = 0b1001_1001;
現在,你可以使用二進制字面量這種表示方式,並且使用非常簡短的代碼,可將二進制字符轉換為數據類型,如在byte或short。
byte aByte = (byte)0b001;
short aShort = (short)0b010;
7 簡化的可變參數調用
當程序員試圖使用一個不可具體化的可變參數並調用一個*varargs* (可變)方法時,編輯器會生成一個“非安全操作”的警告。
JDK 7將警告從call轉移到了方法聲明(methord declaration)的過程中。這樣API設計者就可以使用vararg,因為警告的數量大大減少了。
8 新增一些取環境信息的工具方法
File System.getJavaIoTempDir() // IO臨時文件夾
File System.getJavaHomeDir() // JRE的安裝目錄
File System.getUserHomeDir() // 當前用戶目錄
File System.getUserDir() // 啟動java進程時所在的目錄
9 Boolean類型反轉,空指針安全,參與位運算
Boolean Booleans.negate(Boolean booleanObj)
True => False , False => True, Null => Null
boolean Booleans.and( boolean [] array)
boolean Booleans.or( boolean [] array)
boolean Booleans.xor( boolean [] array)
boolean Booleans.and(Boolean[] array)
boolean Booleans.or(Boolean[] array)
boolean Booleans.xor(Boolean[] array)
10 兩個char間的equals
boolean Character.equalsIgnoreCase( char ch1, char ch2)
11 安全的加減乘除
int Math.safeToInt( long value)
int Math.safeNegate( int value)
long Math.safeSubtract( long value1, int value2)
long Math.safeSubtract( long value1, long value2)
int Math.safeMultiply( int value1, int value2)
long Math.safeMultiply( long value1, int value2)
long Math.safeMultiply( long value1, long value2)
long Math.safeNegate( long value)
int Math.safeAdd( int value1, int value2)
long Math.safeAdd( long value1, int value2)
long Math.safeAdd( long value1, long value2)
int Math.safeSubtract( int value1, int value2)
12 map集合支持並發請求 ,且可以寫成 Map map = {name:"xxx",age:18};
特性1:二進制字面值(Binary Literals)
在java7里,整形(byte,short,int,long)類型的值可以用二進制類型來表示了,在使用二進制的值時,需要在前面加上ob或oB,看代碼
Java代碼
//b 大小寫都可以
int a = 0b01111_00000_11111_00000_10101_01010_10;
short b = (short)0b01100_00000_11111_0;
byte c = (byte)0B0000_0001;
其次,二進制同十進制和十六進制相比,可以一目了然的看出數據間的關系。例如下面這個數組中展示了每次移動一位后數字的變化。
Java代碼
public static final int[] phases = {
0b00110001,
0b01100010,
0b11000100,
0b10001001,
0b00010011,
0b00100110,
0b01001100,
0b10011000
}
如果用十六進制來表示的,它們之間的關系就無法一眼看出來了。
public static final int[] phases = {
0x31, 0x62, 0xC4, 0x89, 0x13, 0x26, 0x4C, 0x98
}
特性2:數字變量對下划線_的支持
你可以在數值類型的變量里添加下滑線,除了以下的幾個地方不能添加:
數字的開頭和結尾
小數點前后
F或者L前
需要出現string類型值的地方(針對用0x或0b表示十六進制和二進制,參考第一點),比如0x101,不能用0_x101
int num = 1234_5678_9;
float num2 = 222_33F;
long num3 = 123_000_111L;
//下面的不行
//數字開頭和結尾
int nu = _123;
int nu = 123_;
//小數點前后
float f = 123_.12;
float f = 123._12;
//F或者L前
long l = 123_L;
float f = 123_F;
//需要出現String的地方
int num = 0_b123;
float f = 0_x123F;
這個,我個人覺得沒什么實際作用,只是可以提升代碼的可讀性。
特性3:switch 對String的支持
這個大家期待很久了,switch終於支持String了
public static void first() { //項目狀態 String status = "approval"; //我們之前經常根據項目狀態不同來進行不同的操作 //目前已經換成enum類型 switch (status) { case "shouli": System.out.println("狀態是受理"); break; case "approval": System.out.println("狀態是審批"); break; case "finish": System.out.println("狀態是結束"); break; default: System.out.println("狀態未知"); } } 每個case是使用String的equals方法來進行比較的,對大小寫敏感。 和一連串的if-else-then想比,使用switch來比較String,Java編譯器會生成更加有效的字節碼,寫一個例子測試一下。 Java代碼 public static void second() { String status = "approval"; if ("shouli".equals(status)) { System.out.println("狀態是受理"); } else if ("approval".equals(status)) { System.out.println("狀態是審批"); } else if ("finish".equals(status)) { System.out.println("狀態是結束"); } else { System.out.println("狀態未知"); } }
使用javap之后,生成字節碼如下:(略)
網上說,用switch之后比用if-else生成的字節碼更有效一些,不過目前至少從長度上來說,switch還是長一些
特性4:try-with-resources 聲明
try-with-resources 是一個定義了一個或多個資源的try 聲明,這個資源是指程序處理完它之后需要關閉它的對象。try-with-resources 確保每一個資源在處理完成后都會被關閉。
可以使用try-with-resources的資源有:
任何實現了java.lang.AutoCloseable 接口和java.io.Closeable 接口的對象。
來看例子:
public static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } 在java 7 以及以后的版本里,BufferedReader實現了java.lang.AutoCloseable接口。 由於BufferedReader定義在try-with-resources 聲明里,無論try語句正常還是異常的結束, 它都會自動的關掉。而在java7以前,你需要使用finally塊來關掉這個對象。 public static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); } } 然而,如果 readLine() 和 close() 這兩個方法都拋出異常,那么readFirstLineFromFileWithFinallyBlock 方法只會拋出后面部分也就是finally塊中的內容,try塊中的異常就被抑制了,對於我們的程序來說,這顯然不是一種好的方式。
而在java 7中,無論是try塊還是try-with-resource中拋出異常,都能捕捉到。 有
另外,一個try-with-resourcse聲明了可以包含多個對象的聲明,用分號隔開,和聲明一個對象相同,會在結束后自動調用close方法,調用順序和生命順序相反。
try (
java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
java.io.BufferedWriter writer = java.nio.file.Files.newBufferedWriter(outputFilePath, charset)
) {
// do something
}
此外,try-with-resources 可以跟catch和finally,catch和finally的是在try-with-resources里聲明的對象關閉之后才執行的。
特性5:捕獲多種異常並用改進后的類型檢查來重新拋出異常
1、捕獲多種異常
在Java SE7里,一個catch可以捕獲多個異常,這樣可以減少重復代碼。每個異常之間用 | 隔開。
public static void first(){ try { BufferedReader reader = new BufferedReader(new FileReader("")); Connection con = null; Statement stmt = con.createStatement(); } catch (IOException | SQLException e) { //捕獲多個異常,e就是final類型的 e.printStackTrace(); } } 而在Java SE6以前,需要這樣寫 Java代碼 public static void second() { try { BufferedReader reader = new BufferedReader(new FileReader("")); Connection con = null; Statement stmt = con.createStatement(); } catch (IOException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } } 注意,如果一個catch處理了多個異常,那么這個catch的參數默認就是final的,你不能在catch塊里修改它的值。
另外,用一個catch處理多個異常,比用多個catch每個處理一個異常生成的字節碼要更小更高效。
2、用更包容性的類型檢查來重新拋出異常
在方法的聲明上,使用throws語句時,你可以指定更加詳細的異常類型。
static class FirstException extends Exception { } static class SecondException extends Exception { } public void rethrowException(String exceptionName) throws Exception { try { if (exceptionName.equals("First")) { throw new FirstException(); } else { throw new SecondException(); } } catch (Exception e) { throw e; } }
這個例子,try塊中只能拋出兩種異常,但是因為catch里的類型是 Exception,在java SE7以前的版本中,在方法聲明中throws 只能寫Exception,但是在java SE7及以后的版本中,可以在throws后面寫 FirstException和SecondException——編譯器能判斷出throw e語句拋出的異常一定來自try塊,並且try塊只能拋出FirstException和SecondException。
public static void reThrowException(String exceptionName) throws FirstException, SecondException{ try { if ("first".equals(exceptionName)) throw new FirstException(); else throw new SecondException(); } catch (Exception e) { throw e; } }
所以盡管catch里的異常類型是Exception,編譯器仍然能夠知道它是FirstException和 SecondException的實例。怎么樣,編譯器變得更智能了吧。
但是,如果在catch里對異常重新賦值了,在方法的throws后無法再象上面那樣寫成FirstException和SecondException了,而需要寫成 Exception。
具體來說,在Java SE 7及以后版本中,當你在catch語句里聲明了一個或多個異常類型,並且在catch塊里重新拋出了這些異常,編譯器根據下面幾個條件來去核實異常的類型:
- Try塊里拋出它
- 前面沒有catch塊處理它
- 它是catch里一個異常類型的父類或子類。
特性6:創建泛型對象時類型推斷
只要編譯器可以從上下文中推斷出類型參數,你就可以用一對空着的尖括號<>來代替泛型參數。這對括號私下被稱為菱形(diamond)。 在Java SE 7之前,你聲明泛型對象時要這樣
List<String> list = new ArrayList<String>();
而在Java SE7以后,你可以這樣
List<String> list = new ArrayList<>();
因為編譯器可以從前面(List)推斷出推斷出類型參數,所以后面的ArrayList之后可以不用寫泛型參數了,只用一對空着的尖括號就行。當然,你必須帶着”菱形”<>,否則會有警告的。
Java SE7 只支持有限的類型推斷:只有構造器的參數化類型在上下文中被顯著的聲明了,你才可以使用類型推斷,否則不行。
List<String> list = new ArrayList<>();
list.add("A");
//這個不行
list.addAll(new ArrayList<>());
// 這個可以
List<? extends String> list2 = new ArrayList<>();
list.addAll(list2);
想必做Java的技術人員們都非常關心Java 7在2010年會有哪些新的進展,這個問題起源於今年年底即將發布的Java 7,那么這些新的特性更新對我們有哪些好處、該如何使用、性能如何,都是大家密切關注的問題。
這里的內容主要包括其最 新更新、一些代碼實例、跟以前版本的Java進行性能比較需要參考的一些基准、以及什么時候它才會發布等信息。
首先,讓我們來看最重要 的事情。為了確定JDK 7中有哪些語言方面的微小變化,有關人員建立了一個名叫Project Coin的項目。描述了最終的五個變化(比五個多一點)。
Java 7更新內容如下所示:
◆允許在 switch中使用字符串
◆自動資源管理
◆通用實例創建來改進類型推斷(diamond)
◆簡化 的Varargs方法調用
◆更好的整型文字綜合性建議
◆Collections集合的語言支持
◆JSR292的語言支持
在the OpenJDK 7特性頁面中,你還可以看到其他的功能。
這些功能分為不同的種類:
◆虛擬機(VM)
◆壓縮的64位對象指針
◆G1垃圾回收器GC(G1)
◆JSR 292:非Java語言的虛擬機支持(動態調用,InvokeDynamic)
語言方面(lang)
◆SR 294:模塊化編程的語言以及虛擬機支持
◆JSR 308:Java類型注釋
◆語言微小增強(我所談論的 Project Coin)
◆JSR TBD: Project Lambda
內核(core)
◆模塊化(Jigsaw項目)
◆對類加載器的結構進行升級
◆關閉URLClassLoader的方法
◆Unicode 5.1標准
◆並行以及集合的升級(jsr166y)
◆JSR 203:Java平台(NIO.2)的更多新型I/O API
◆SCTP (流控制傳輸協議,Stream Control Transmission Protocol)
◆SDP (套接字直接協議,Sockets Direct Protocol)
◆橢圓曲線加密技術(ECC)
客戶端(client)
◆Java 2D的XRender管道
◆轉發端口6u10部署特性
◆為6u10圖形功能創建新的平台API
◆Swing的Nimbus外觀和感覺
◆Swing的JLayer元件
網絡(web)
◆ 更新XML的棧
就像你所看到的,這涉及了很多東西。幾個月前,我親自嘗試了新的Garbage Collector (GC),其性能表現給我留下了非常深刻的印象。不幸的是,JVM幾個小時就會崩潰一次,所以這個產品不能使用JVM。雖然在Java 1.6中也可以使用這個GC,但也會出現同樣的問題,經常會出現崩潰。
我想,這就是Java1.7增加新特性的原因。那么,現在我們最好去看一些代碼實例。
Java 7新特性的代碼實例
下面列出的大多數例子都是來源於Joe Wright博客中(Java7中的新語言特性)的高水平文章。
集合的語言支持
在這里我們主要講的 是,當創建一個List、Set或者Map的時候,你怎樣盡量少寫代碼。你不必先實例化Object,然后再給Collection添加元素。你現在只需 1行代碼就可以完成。
List list = ["item"];
String item = list[0];
Set set = {"item"};
Map map = {"key" : 1};
int value = map["key"];
自動資源管理
由於try / catch語句的原因,冗長的代碼令人非常頭痛。你或許會喜歡這個全新的特性。
實際上,下面這些代碼:
BufferedReader br = new BufferedReader(new FileReader(path));
try {
return br.readLine();
}
finally
{
br.close();
}
轉變成了如下這種形式:
try (BufferedReader br = new BufferedReader(new FileReader(path)) {
return br.readLine();
}
通用實例創建來改進類型推斷(diamond)
當你把對象的接口申明指定成范型后,你在對象實例化時不得不再指定一次。現 在,你不必如此了,因為你可以這樣:
Map> map = new HashMap<>();
數值文字的加強
我不敢肯定這個對大多數人都有用。你可以這樣做:
int billion = 1_000_000_000;
允許在 switch中使用字符串
這個無需解釋,其意思很明確。
String availability = "available";
switch(availability)
{
case "available":
//code
break;
case "unavailable":
//code
break;
case "merged":
//code
default:
//code
break;
}
二進制文字
你可以使用前綴0b創建二進制文字
int binary = 0b1001_1001;
以上這些就 是Java1.7的代碼實例。如果有人能給我指出還有哪些沒有包含進去,那就更好了。我敢肯定,已經有其他的開發人員對此進行了關注。
Java 1.7的性能表現
Java 7的性能有多大的提升?這里我們來針對Java 7做一個測試,內容如下。在一台裝有ArchLinux系統的Macbook Pro電腦上(因特爾Duo CPU T7700,主頻2.40GHz,有兩年的使用時間)運行了這些測試。內存是2Gb的,把Heap Size設置成了728m(-Xms728m -Xmx728m)。
◆測試1 為一個List添加100萬個字符串值(String字符串是一個UUID,是用UUID.randomUUID()產生的)。
◆測試 2 帶有100萬鍵、值對的HashMap。每個鍵、值對通過並行線程進行計算。鍵是一個UUID,值int是用Math.random()產生的。
◆測試3 把100萬個ArrayList條目打印到一定數量的文件(1000個)中。把條目寫進恰巧並行的不同文件中。
我只比較了 Java1.6 (1.6.0_19) 和 Java 1.7 (b87)。后來根據評論的要求,我把Java1.5也添加了進來,但是並沒有添加Java1.4,因為它的時間太久遠了。
結果如下所示:
Java 7的發布日期
預計2009年11月Java 7將正式發布,原計划在2010年9月發布,到那時還將發布3個里程碑版本。其中,里程碑6在build 84版中已經完成,里程碑7的第一個測試版B85也計划在2010年3月4日完成,而本文使用的B87版本已在2010年3月25日發布。這樣看起來,Java 7很有可能在2010年9月發布。讓我們拭目以待吧!