一起學Java7新功能擴展 - 深入歷險分享
一:java7語言擴展的簡介
2011年7月,在時隔數年之后,java的一個重大版本javase7發布了。在這個新的版本中,java平臺新增了很多的新的特性。在java虛擬機方面,invokedynamic指令的加入使虛擬機上的動態語言的性能得到了很大的提升。這使得開發人員可以享受到動態語言帶來的在提高生產效率方面的好處。在java語言方面,語言本身的進一步簡化,使開發人員編寫代碼的效率更高。在java類庫方面,新的IO庫和同步實現工具類為開發人員提供了更多的實現功能。從另外一個角度來說,javase7是oracle公司領導力的顧慮。Javase7的發布也證明了jcp和openjdk的社區驅動模式可以很好地推動java向前發展。
隨著新版本的發布,肯定會有越來越多的開發人員想嘗試使用javase7中的新特性,畢竟開發者社區對這個新版本的期待了太長的時間。在java程序中使用這些新特性,可以提高代碼質量,提升工作效率。Java平臺的每個版本都致力于提高java程序的運行性能。同時隨著新版本的發布,企業都應該考慮把java程序的運行平臺升級到最新的javase7,這樣可以享受到性能提升所帶來的好處。對于新的java程序開發,推薦使用javase7作為標準的運行平臺。
在介紹具體的新特性之前,有必要介紹一下coin項目。OpenJDK中的Coin項目的目的是維護對java語言所做的語法增強。在Coin項目開始之初,曾經廣泛地向社區征求提議。在短短一個月時間內就收到了近70條提議。最后有9條提議被列入考慮之中。在這9條提議中,有6條成為java7的一部分,剩下的6提議會在java8中重新考慮,還有1條提議被移到其他項目中實現。這6條被接納的提議除了switch語句中使用字符串、數值字面的改進、優化的異常處理、try-with-resources語句和優化變長參數的方法調用之外還有簡化泛型類創建的“<>”操作符。在java8中考慮2條提議則分別是集合類字面量和為List和Map提供類似數組的按序號的訪問方式。
和其他對java平臺所做的修改一樣,Coin項目所建議的修改也需要通過JCP來完成。這些改動以JSR334(Small Enhancements to the Java)
二:java7中 switch特性介紹
今天首先來讓我們看看耳熟能詳的switch是如何被提升擴展對字符串的支持的!大家都知道在java7之前switch語句中的條件表達式的類型只能是與整數類型兼容的類型,包括基本類型char、byte、short和int,與這些基本類型對應的封裝類型Character、Byte、Short和Integer,還有枚舉類型。這樣的限制降低了語言的靈活性,使開發人員在需要根據其他類型的表達式來進行條件選擇時,不得不增加額外的代碼來繞過這個限制。為此java7放寬了這個限制,額外增加了一種可以在switch語句中使用的表達式類型,那就是很常見的字符串,即String類型
三:java7中switch用法
在基本java7的代碼中使用這個新特性非常簡單,因為這個新特性并沒有改變switch的語法含義,只是多了一種開發人員可以選擇的條件判斷的數據類型。但是這個簡單的新特性卻帶來了重大的影響,因為根據字符串進行條件判斷在開發中是很常見的。
下面來看看java7中根據字符串進行條件判斷【Test】:
public class Test { public String getTitle(String name,String sex){ String title =""; switch(sex){ case "男": title=name+"\t it man"; break; case "女": title=name+"\t it woman"; break; default: title=name+"變形金剛"; } return title; } public static void main(String[] args) { System.out.println(new Test().getTitle("Dobby", "男")); } }
運行結果:
PS:在switch語句中,表達式的值是不能是null,否則會在運行時拋出NullPointerException,在case子句中也不能使用null,否則會出現編譯錯誤。
看到這里或許你覺得這個沒什么嘛就是一個簡單的switch,你別著急接下來就是switch的深度歷險了,讓我們看看他是如何實現switch接受String類型的!根據switch語句的語法要求,其case子句的值是不能重復的,這個要求對字符串類型的條件表達式同樣適用。不過對于字符串來說這種重復值的檢查還有一個特殊之處,就是java代碼中的字符串可以包含Unicode轉義字符。重復值的檢查是在java編譯器對java源碼進行相關的語法轉換之后才進行的。這個語法轉換過程中包括了對Unicode轉義字符的處理。也就是說,有些case子句的值雖然在源碼中看起來是不同的,但是經過轉換后是一樣的,這個就會造成編譯錯誤。
修改上面的代碼再執行看看如下修改(使用jdk自帶的native2ascii.exe將“女”轉換成Unicode):
public String getTitle(String name,String sex){ String title =""; switch(sex){ case "男": title=name+"\t it man"; break; case "\u7537": title=name+"\t it woman"; break; default: title=name+"變形金剛"; } return title; }
當我們再次編譯的時候就會不通過,報出標簽重復錯誤!
這是因為其中的switch語句中的兩個case子句所使用的值“男”和“\u7537”在經過轉義之后變成一樣的。“\u7537”是“男”的Unicode轉義字符形式。
四.java7 switch實現原理
說了這么多下面讓我們來看看switch究竟是如何實現的呢!實際上,這個新特性是在編譯器這個層次上實現的。而在java虛擬機和字節碼這個層次上,還是只支持在switch語句中使用與整數類型兼容的類型。這么做的目的是為了減少這個特性所影響的范圍,以降低實現的代價。在編譯器層次實現的含義是,雖然開發人員在java源碼的switch語句中使用了字符串類型,但是編譯的過程中,編譯器會根據源代碼的含義來進行轉換,將字符串類型轉換成與整數兼容的格式。不同的java編譯器可能采用不同的方式來完成這個轉換,并采用不同的優化策略。比如:如果switch子句中只包含一個case子句,那么可以簡單的將其轉換成一個if語句。如果switch語句中包含一個case子句和一個default子句,那么可以將其轉換成if-else語句。而對于最復雜的情況,只不過使用字符串的哈希值作為switch語句的表達式的值。
為了驗證剛剛的理論同時我們也探究OpenJDK中的java編譯器使用的是什么樣的轉換方式,需要一個名為JAD的工具,這個工具可以把java的class文件反編譯成java源碼,下面我們使用JAD把剛剛的Test.class文件反編譯。在對編譯生成Test類的class文件使用了JAD之后,所得到的內容如下:
從上面的代碼中可以看出,原來用在switch語句中的字符串被替換成了對應的哈希值,而case子句的值也被替換成原來字符串常用的哈希值。經過這樣的轉換,java虛擬機所看到的仍然是與整數類型兼容的類型。在這里值得注意的是,在case子句對應的語句塊中仍然需要使用String的equals方法來進行字符串比較。這是因為哈希函數在映射的時候可能存在沖突,多個字符串的哈希值可能是一樣的。進行字符串比較是為了保證轉換之后的代碼邏輯與之前完全一樣!
好了今日歷險到此,java7里面的變革還是很大的這里就先分享一則!后面基本分為有以下方面:
1. 語法新特性:對數值字面量的改進、優化的異常處理、try-with-resources語句、優化變長參數的方法調用、
2. Java語言的動態性:腳本語言支持API、反射API、動態代理、動態語言支持、
3. Java7其他重要更新:關系數據庫訪問、javalang包更新、java實用工具類、JavaBeans組件
4. 超越java7:lambda表達式、java平臺模塊化、javaSe8的其他更新
想必大家機子上一定更新到 java7 了吧!只是沒有幾個人用過吧!接下來就是自己動手歷險的時候了!實踐是檢驗真理的唯一標準!(如果沒有的自己可以到 oracle 官方下載 java7 jdk )這里透露一下哦, eclipse 最新版也已經集成了 java7 可以到官方下載,不過默認的還是 6 的版本,自己創建項目的時候可以選擇,如果發現可以 jre 沒有集成, 自己可以添加 java7 的 jre 到 eclipse 就可以使用了!好了初試 java7 到此結束!后面慢慢在學習!
轉自:http://my.oschina.net/BeyondBit/blog/76268