jdk7和8的一些新特性介紹

更多ppt內容請查看:http://www.javaarch.net/jiagoushi/927.htmhtml


 

本文是我學習瞭解了jdk7和jdk8的一些新特性的一些資料,有興趣的你們能夠瀏覽下下面的內容。
官方文檔:http://www.oracle.com/technetwork/java/javase/jdk7-relnotes-418459.html

在jdk7的新特性方面主要有下面幾方面的加強:

1.jdk7語法上

   1.1二進制變量的表示,支持將整數類型用二進制來表示,用0b開頭。

   // 全部整數 int, short,long,byte均可以用二進制表示
	// An 8-bit 'byte' value:
	byte aByte = (byte) 0b00100001;

	// A 16-bit 'short' value:
	short aShort = (short) 0b1010000101000101;

	// Some 32-bit 'int' values:
	intanInt1 = 0b10100001010001011010000101000101;
	intanInt2 = 0b101;
	intanInt3 = 0B101; // The B can be upper or lower case.

	// A 64-bit 'long' value. Note the "L" suffix:
	long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L;

	// 二進制在數組等的使用
	final int[] phases = { 0b00110001, 0b01100010, 0b11000100, 0b10001001,
	0b00010011, 0b00100110, 0b01001100, 0b10011000 };

1.2  Switch語句支持string類型 

	   public static String getTypeOfDayWithSwitchStatement(String dayOfWeekArg) {
		 String typeOfDay;
		 switch (dayOfWeekArg) {
			 case "Monday":
				 typeOfDay = "Start of work week";
				 break;
			 case "Tuesday":
			 case "Wednesday":
			 case "Thursday":
				 typeOfDay = "Midweek";
				 break;
			 case "Friday":
				 typeOfDay = "End of work week";
				 break;
			 case "Saturday":
			 case "Sunday":
				 typeOfDay = "Weekend";
				 break;
			 default:
				 throw new IllegalArgumentException("Invalid day of the week: " + dayOfWeekArg);
		 }
		 return typeOfDay;
	} 

1.3 Try-with-resource語句 
  
  注意:實現java.lang.AutoCloseable接口的資源均可以放到try中,跟final裏面的關閉資源相似; 按照聲明逆序關閉資源 ;Try塊拋出的異常經過Throwable.getSuppressed獲取 

	try (java.util.zip.ZipFile zf = new java.util.zip.ZipFile(zipFileName);
	java.io.BufferedWriter writer = java.nio.file.Files 
	.newBufferedWriter(outputFilePath, charset)) {
	// Enumerate each entry
	for (java.util.Enumeration entries = zf.entries(); entries
	.hasMoreElements();) {
	// Get the entry name and write it to the output file
	String newLine = System.getProperty("line.separator");
	String zipEntryName = ((java.util.zip.ZipEntry) entries
	.nextElement()).getName() + newLine;
	writer.write(zipEntryName, 0, zipEntryName.length());
	}
	}

1.4 Catch多個異常 說明:Catch異常類型爲final; 生成Bytecode 會比多個catch小; Rethrow時保持異常類型 

	public static void main(String[] args) throws Exception {
	try {
	testthrows();
	} catch (IOException | SQLException ex) {
	throw ex;
	}
	}
	public static void testthrows() throws IOException, SQLException {
	}

1.5 數字類型的下劃線表示 更友好的表示方式,不過要注意下劃線添加的一些標準,能夠參考下面的示例

	long creditCardNumber = 1234_5678_9012_3456L;
	long socialSecurityNumber = 999_99_9999L;
	float pi = 3.14_15F;
	long hexBytes = 0xFF_EC_DE_5E;
	long hexWords = 0xCAFE_BABE;
	long maxLong = 0x7fff_ffff_ffff_ffffL;
	byte nybbles = 0b0010_0101;
	long bytes = 0b11010010_01101001_10010100_10010010; 
	//float pi1 = 3_.1415F;      // Invalid; cannot put underscores adjacent to a decimal point
	//float pi2 = 3._1415F;      // Invalid; cannot put underscores adjacent to a decimal point
	//long socialSecurityNumber1= 999_99_9999_L;         // Invalid; cannot put underscores prior to an L suffix 
	//int x1 = _52;              // This is an identifier, not a numeric literal
	int x2 = 5_2;              // OK (decimal literal)
	//int x3 = 52_;              // Invalid; cannot put underscores at the end of a literal
	int x4 = 5_______2;        // OK (decimal literal) 
	//int x5 = 0_x52;            // Invalid; cannot put underscores in the 0x radix prefix
	//int x6 = 0x_52;            // Invalid; cannot put underscores at the beginning of a number
	int x7 = 0x5_2;            // OK (hexadecimal literal)
	//int x8 = 0x52_;            // Invalid; cannot put underscores at the end of a number 
	int x9 = 0_52;             // OK (octal literal)
	int x10 = 05_2;            // OK (octal literal)
	//int x11 = 052_;            // Invalid; cannot put underscores at the end of a number 
	1.6 泛型實例的建立能夠經過類型推斷來簡化 能夠去掉後面new部分的泛型類型,只用<>就能夠了。
	  //使用泛型前 
	List strList = new ArrayList(); 
	List<String> strList4 = new ArrayList<String>(); 
	List<Map<String, List<String>>> strList5 =  new ArrayList<Map<String, List<String>>>();

	 
	//編譯器使用尖括號 (<>) 推斷類型 
	List<String> strList0 = new ArrayList<String>(); 
	List<Map<String, List<String>>> strList1 =  new ArrayList<Map<String, List<String>>>(); 
	List<String> strList2 = new ArrayList<>(); 
	List<Map<String, List<String>>> strList3 = new ArrayList<>();
	List<String> list = new ArrayList<>();
	list.add("A");
	  // The following statement should fail since addAll expects
	  // Collection<? extends String>
	//list.addAll(new ArrayList<>()); 

1.7在可變參數方法中傳遞非具體化參數,改進編譯警告和錯誤 

Heap pollution 指一個變量被指向另一個不是相同類型的變量。例如

	List l = new ArrayList<Number>();
	List<String> ls = l;       // unchecked warning
	l.add(0, new Integer(42)); // another unchecked warning
	String s = ls.get(0);      // ClassCastException is thrown
	Jdk7:
	public static <T> void addToList (List<T> listArg, T... elements) {
	for (T x : elements) {
	listArg.add(x);
	}
	}
	你會獲得一個warning
	warning: [varargs] Possible heap pollution from parameterized vararg type
	要消除警告,能夠有三種方式
	1.加 annotation @SafeVarargs 
	2.加 annotation @SuppressWarnings({"unchecked", "varargs"})
	3.使用編譯器參數 –Xlint:varargs;

  1.8 信息更豐富的回溯追蹤 就是上面try中try語句和裏面的語句同時拋出異常時,異常棧的信息

    java.io.IOException  
	§?      at Suppress.write(Suppress.java:19)  
	§?      at Suppress.main(Suppress.java:8)  
	§?      Suppressed:  java.io.IOException 
	§?          at Suppress.close(Suppress.java:24) 
	§?          at Suppress.main(Suppress.java:9)  
	§?      Suppressed:  java.io.IOException 
	§?          at  Suppress.close(Suppress.java:24)  
	§?          at  Suppress.main(Suppress.java:9) 
	 

2. NIO2的一些新特性
	
	1.java.nio.file 和java.nio.file.attribute包 支持更詳細屬性,好比權限,全部者 
	2.  symbolic and hard links支持 
	3. Path訪問文件系統,Files支持各類文件操做 
	4.高效的訪問metadata信息 
	5.遞歸查找文件樹,文件擴展搜索 
	6.文件系統修改通知機制 
	7.File類操做API兼容 
	8.文件隨機訪問加強 mapping a region,locl a region,絕對位置讀取 
	9. AIO Reactor(基於事件)和Proactor 

  下面列一些示例:

2.1IO and New IO 監聽文件系統變化通知 

經過FileSystems.getDefault().newWatchService()獲取watchService,而後將須要監聽的path目錄註冊到這個watchservice中,對於這個目錄的文件修改,新增,刪除等實踐能夠配置,而後就自動能監聽到響應的事件。

	private WatchService watcher; 
	public TestWatcherService(Path path) throws IOException {
	watcher = FileSystems.getDefault().newWatchService();
	path.register(watcher, ENTRY_CREATE, ENTRY_DELETE, ENTRY_MODIFY);
	} 
	public void handleEvents() throws InterruptedException {
	while (true) {
	WatchKey key = watcher.take();
	for (WatchEvent<?> event : key.pollEvents()) {
	WatchEvent.Kind kind = event.kind();
	if (kind == OVERFLOW) {// 事件可能lost or discarded
	continue;
	}
	WatchEvent<Path> e = (WatchEvent<Path>) event;
	Path fileName = e.context();
	System.out.printf("Event %s has happened,which fileName is %s%n",kind.name(), fileName);
	}
	if (!key.reset()) {
	break;
	}

2.2 IO and New IO遍歷文件樹 ,經過繼承SimpleFileVisitor類,實現事件遍歷目錄樹的操做,而後經過Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);這個API來遍歷目錄樹

	private void workFilePath() {
	Path listDir = Paths.get("/tmp"); // define the starting file 
	ListTree walk = new ListTree();
	…Files.walkFileTree(listDir, walk);…
	// 遍歷的時候跟蹤連接
	EnumSet opts = EnumSet.of(FileVisitOption.FOLLOW_LINKS);
	try {
	Files.walkFileTree(listDir, opts, Integer.MAX_VALUE, walk);
	} catch (IOException e) {
	System.err.println(e);
	}
	class ListTree extends SimpleFileVisitor<Path> {// NIO2 遞歸遍歷文件目錄的接口 
	@Override
	public FileVisitResult postVisitDirectory(Path dir, IOException exc) {
	System.out.println("Visited directory: " + dir.toString());
	return FileVisitResult.CONTINUE;
	} 
	@Override
	public FileVisitResult visitFileFailed(Path file, IOException exc) {
	System.out.println(exc);
	return FileVisitResult.CONTINUE;
	}
	}


2.3 AIO異步IO 文件和網絡 異步IO在java 
 NIO2實現了,都是用AsynchronousFileChannel,AsynchronousSocketChanne等實現,關於同步阻塞IO,同步非阻塞IO,異步阻塞IO和異步非阻塞IO在ppt的這頁上下面備註有說明,有興趣的能夠深刻了解下。Java NIO2中就實現了操做系統的異步非阻塞IO。

	// 使用AsynchronousFileChannel.open(path, withOptions(),  
		// taskExecutor))這個API對異步文件IO的處理  
		public static void asyFileChannel2() {  
			final int THREADS = 5;  
			ExecutorService taskExecutor = Executors.newFixedThreadPool(THREADS);  
			String encoding = System.getProperty("file.encoding");  
			List<Future<ByteBuffer>> list = new ArrayList<>();  
			int sheeps = 0;  
			Path path = Paths.get("/tmp",  
					"store.txt");  
			try (AsynchronousFileChannel asynchronousFileChannel = AsynchronousFileChannel  
					.open(path, withOptions(), taskExecutor)) {  
				for (int i = 0; i < 50; i++) {  
					Callable<ByteBuffer> worker = new Callable<ByteBuffer>() {  
						@Override  
						public ByteBuffer call() throws Exception {  
							ByteBuffer buffer = ByteBuffer  
									.allocateDirect(ThreadLocalRandom.current()  
											.nextInt(100, 200));  
							asynchronousFileChannel.read(buffer, ThreadLocalRandom  
	……

		
3. JDBC 4.1

3.1.可使用try-with-resources自動關閉Connection, ResultSet, 和 Statement資源對象 

3.2. RowSet 1.1:引入RowSetFactory接口和RowSetProvider類,能夠建立JDBC driver支持的各類 row sets,這裏的rowset實現其實就是將sql語句上的一些操做轉爲方法的操做,封裝了一些功能。

3.3. JDBC-ODBC驅動會在jdk8中刪除 

	try (Statement stmt = con.createStatement()) { 
	 RowSetFactory aFactory = RowSetProvider.newFactory();
	  CachedRowSet crs = aFactory.createCachedRowSet();
	  
	 RowSetFactory rsf = RowSetProvider.newFactory("com.sun.rowset.RowSetFactoryImpl", null);
	WebRowSet wrs = rsf.createWebRowSet();
	createCachedRowSet 
	createFilteredRowSet 
	createJdbcRowSet 
	createJoinRowSet 
	createWebRowSet 


4. 併發工具加強 

4.1.fork-join 
 最大的加強,充分利用多核特性,將大問題分解成各個子問題,由多個cpu能夠同時解決多個子問題,最後合併結果,繼承RecursiveTask,實現compute方法,而後調用fork計算,最後用join合併結果。

	class Fibonacci extends RecursiveTask<Integer> {
	final int n;
	Fibonacci(int n) {
	this.n = n;
	}
	private int compute(int small) {
	final int[] results = { 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89 };
	return results[small];
	}
	public Integer compute() {
	if (n <= 10) {
	return compute(n);
	}
	Fibonacci f1 = new Fibonacci(n - 1);
	Fibonacci f2 = new Fibonacci(n - 2);
	System.out.println("fork new thread for " + (n - 1));
	f1.fork();
	System.out.println("fork new thread for " + (n - 2));
	f2.fork();
	return f1.join() + f2.join();
	}
	} 

 4.2.ThreadLocalRandon 併發下隨機數生成類,保證併發下的隨機數生成的線程安全,實際上就是使用threadlocal

    final int MAX = 100000;
	ThreadLocalRandom threadLocalRandom = ThreadLocalRandom.current();
	long start = System.nanoTime();
	for (int i = 0; i < MAX; i++) {
	threadLocalRandom.nextDouble();
	}
	long end = System.nanoTime() - start;
	System.out.println("use time1 : " + end);
	long start2 = System.nanoTime();
	for (int i = 0; i < MAX; i++) {
	Math.random();
	}
	long end2 = System.nanoTime() - start2;
	System.out.println("use time2 : " + end2); 

	   
4.3. phaser 相似cyclebarrier和countdownlatch,不過能夠動態添加資源減小資源

	 void runTasks(List<Runnable> tasks) {
	final Phaser phaser = new Phaser(1); // "1" to register self
	// create and start threads
	for (final Runnable task : tasks) {
	phaser.register();
	new Thread() {
	public void run() {
	phaser.arriveAndAwaitAdvance(); // await all creation
	task.run();
	}
	}.start();
	}
	// allow threads to start and deregister self
	phaser.arriveAndDeregister();
	} 

5. Networking加強 

新增URLClassLoader close方法,能夠及時關閉資源,後續從新加載class文件時不會致使資源被佔用或者沒法釋放問題
URLClassLoader.newInstance(new URL[]{}).close();
新增Sockets Direct Protocol
繞過操做系統的數據拷貝,將數據從一臺機器的內存數據經過網絡直接傳輸到另一臺機器的內存中 

6. Multithreaded Custom Class Loaders  
    
	解決併發下加載class可能致使的死鎖問題,這個是jdk1.6的一些新版本就解決了,jdk7也作了一些優化。有興趣能夠仔細從官方文檔詳細瞭解

jdk7前:
  
	Class Hierarchy:            
	  class A extends B
	  class C extends D
	ClassLoader Delegation Hierarchy:
	Custom Classloader CL1:
	  directly loads class A 
	  delegates to custom ClassLoader CL2 for class B
	Custom Classloader CL2:
	  directly loads class C
	  delegates to custom ClassLoader CL1 for class D
	Thread 1:
	  Use CL1 to load class A (locks CL1)
		defineClass A triggers
		  loadClass B (try to lock CL2)
	Thread 2:
	  Use CL2 to load class C (locks CL2)
		defineClass C triggers
		  loadClass D (try to lock CL1)
	Synchronization in the ClassLoader class wa 

jdk7

	Thread 1:
	  Use CL1 to load class A (locks CL1+A)
		defineClass A triggers
		  loadClass B (locks CL2+B)
	Thread 2:
	  Use CL2 to load class C (locks CL2+C)
		defineClass C triggers
		  loadClass D (locks CL1+D) 


7. Security 加強 

	7.1.提供幾種 ECC-based algorithms (ECDSA/ECDH) Elliptic Curve Cryptography (ECC)
	7.2.禁用CertPath Algorithm Disabling
	7.3. JSSE (SSL/TLS)的一些加強 

8. Internationalization 加強 增長了對一些編碼的支持和增長了一些顯示方面的編碼設置等
	
	1. New Scripts and Characters from Unicode 6.0.0
	2. Extensible Support for ISO 4217 Currency Codes
	Currency類添加:      
		   getAvailableCurrencies 
		   getNumericCode 
		   getDisplayName 
		   getDisplayName(Locale)
	3. Category Locale Support
	 getDefault(Locale.Category)FORMAT  DISPLAY 
	4. Locale Class Supports BCP47 and UTR35
		   UNICODE_LOCALE_EXTENSION
		   PRIVATE_USE_EXTENSION
		   Locale.Builder 
		   getExtensionKeys()
		   getExtension(char)
		   getUnicodeLocaleType(String
			……
	5. New NumericShaper Methods
	NumericShaper.Range 
	getShaper(NumericShaper.Range) 
	getContextualShaper(Set<NumericShaper.Range>)…… 


9.jvm方面的一些特性加強,下面這些特性有些在jdk6中已經存在,這裏作了一些優化和加強。

1.Jvm支持非java的語言 invokedynamic 指令 

2. Garbage-First Collector 適合server端,多處理器下大內存,將heap分紅大小相等的多個區域,mark階段檢測每一個區域的存活對象,compress階段將存活對象最小的先作回收,這樣會騰出不少空閒區域,這樣併發回收其餘區域就能減小中止時間,提升吞吐量。 

3. HotSpot性能加強 
    Tiered Compilation  -XX:+UseTieredCompilation 多層編譯,對於常常調用的代碼會直接編譯程本地代碼,提升效率
   Compressed Oops  壓縮對象指針,減小空間使用
  Zero-Based Compressed Ordinary Object Pointers (oops) 進一步優化零基壓縮對象指針,進一步壓縮空間

4. Escape Analysis  逃逸分析,對於只是在一個方法使用的一些變量,能夠直接將對象分配到棧上,方法執行完自動釋放內存,而不用經過棧的對象引用引用堆中的對象,那麼對於對象的回收可能不是那麼及時。

5. NUMA Collector Enhancements  

NUMA(Non Uniform Memory Access),NUMA在多種計算機系統中都獲得實現,簡而言之,就是將內存分段訪問,相似於硬盤的RAID,Oracle中的分簇 

10. Java 2D Enhancements

	1. XRender-Based Rendering Pipeline -Dsun.java2d.xrender=True
	2. Support for OpenType/CFF Fonts GraphicsEnvironment.getAvailableFontFamilyNames 
	3. TextLayout Support for Tibetan Script
	4. Support for Linux Fonts

11. Swing Enhancements

	1.	JLayer 
	2.	Nimbus Look & Feel
	3.	Heavyweight and Lightweight Components
	4.	Shaped and Translucent Windows
	5.	Hue-Saturation-Luminance (HSL) Color Selection in JColorChooser Class



12. Jdk8 lambda表達式 最大的新增的特性,不過在不少動態語言中都已經原生支持。

原來這麼寫:

	btn.setOnAction(new EventHandler<ActionEvent>() { 
		@Override 
		public void handle(ActionEvent event) { 
			System.out.println("Hello World!"); 
		} 
	}); 
       
jdk8直接能夠這麼寫:

	btn.setOnAction( 
		event -> System.out.println("Hello World!") 
	);   
	   
更多示例:
   
	public class Utils { 
		public static int compareByLength(String in, String out){ 
			return in.length() - out.length(); 
		} 
	} 

	public class MyClass { 
		public void doSomething() { 
			String[] args = new String[] {"microsoft","apple","linux","oracle"} 
			Arrays.sort(args, Utils::compareByLength); 
		}  
	}  

13.jdk8的一些其餘特性,固然jdk8的加強功能還有不少,你們能夠參考http://openjdk.java.net/projects/jdk8/

用Metaspace代替PermGen 
動態擴展,能夠設置最大值,限制於本地內存的大小 
Parallel array sorting 新APIArrays#parallelSort.

	New Date & Time API
	Clock clock = Clock.systemUTC(); //return the current time based on your system clock and set to UTC.

	Clock clock = Clock.systemDefaultZone(); //return time based on system clock zone 

	long time = clock.millis(); //time in milliseconds from January 1st, 1970 

更多內容能夠看看附件ppt,示例代碼能夠參考:https://github.com/zhwj184/jdk7-8demo




相關文章
相關標籤/搜索