1. 可以用二進制表達數字
可以用二進制表達數字(加前綴0b/0B),包括:byte, short, int, long
// 可以用二進制表達數字(加前綴0b/0B),包括:byte, short, int, long @Test public void testLiterals() { // An 8-bit 'byte' value: byte aByte = (byte)0b00100001; // A 16-bit 'short' value: short aShort = (short)0b1010000101000101; // Some 32-bit 'int' values: int anInt1 = 0b10100001010001011010000101000101; int anInt2 = 0b101; int anInt3 = 0B101; // The B can be upper or lower case. // A 64-bit 'long' value. Note the "L" suffix: long aLong = 0b1010000101000101101000010100010110100001010001011010000101000101L; // 來個簡單版本的 byte b = 0b10; short s = 0B100; int i = 0b1000; long l = 0B10000; System.out.println(b + "|" + s + "|" + i + "|" + l); // ->輸出將會是2|4|8|16 }
2. 可以對數字加下划線
可以對數字加下划線以讓變量表達得更清楚些;注意:符號“.”左右不可以用下划線、還包括“L/F/0x"等等。
// 可以對數字加下划線以讓變量表達得更清楚些 // 注意:符號“.”左右不可以用下划線、還包括“L/F/0x"等等。 @Test public void testUnderscores() { 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; System.out.println(creditCardNumber + "|" + socialSecurityNumber); // ->下划線僅供代碼中直觀查看,輸出時自動去掉了;輸出將會是:1234567890123456|999999999 }
3. switch中可以使用字符串了
// switch中可以使用字符串了 public 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; }
4. 泛型實例化類型自動推斷
// 泛型實例化類型自動推斷 @Test public void testGeneric() { // 舊版本 Map<String, List<String>> myMap1 = new HashMap<String, List<String>>(); // 新版本 Map<String, List<String>> myMap2 = new HashMap<>(); List<String> list = new ArrayList<>(); list.add("A"); // 下面這條語句編譯不過;如果改成:new ArrayList<String>()則可以。 // list.addAll(new ArrayList<>()); }
5. “非安全操作”的警告
當使用一個不可具體化的參數(Non-Reifiable Formal Parameters)調用一個可變參數方法(Varargs Methods )編輯器會生成一個“非安全操作”的警告。
package com.clzhang.sample.thinking; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.junit.Test; /** * 當使用一個不可具體化的參數(Non-Reifiable Formal Parameters)調用一個可變參數方法(Varargs Methods ) * 編輯器會生成一個“非安全操作”的警告。 * @author acer * */ public class ArrayBuilder { //Type safety: Potential heap pollution via varargs parameter elements public static <T> void addToList(List<T> listArg, T... elements) { for (T x : elements) { listArg.add(x); } } //Type safety: Potential heap pollution via varargs parameter l @SafeVarargs public static void faultyMethod(List<String>... l) { Object[] objectArray = l; // Valid // 這一行代碼把列表中的數據類型給改變了! objectArray[0] = Arrays.asList(new Integer(42)); // 下面再取值,會報錯;因為里面已經不再是String類型的數據,而是Integer類型的數據。 String s = l[0].get(0); // ClassCastException thrown here // 如果注釋掉本方法中的第2行代碼,則此條語句可以執行;否則,執行不到這里。 System.out.println("first param is:" + s); } @Test public void testHeapPollution() { List<String> stringListA = new ArrayList<String>(); List<String> stringListB = new ArrayList<String>(); ArrayBuilder.addToList(stringListA, "Seven", "Eight", "Nine"); ArrayBuilder.addToList(stringListA, "Ten", "Eleven", "Twelve"); List<List<String>> listOfStringLists = new ArrayList<List<String>>(); ArrayBuilder.addToList(listOfStringLists, stringListA, stringListB); ArrayBuilder.faultyMethod(Arrays.asList("Hello!"), Arrays.asList("World!")); } }
6. 對資源的自動回收管理
// JDK1.7之前的做法,需要在finally塊中關閉相關資源 String readFirstLineFromFileWithFinallyBlock(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { if (br != null) br.close(); } } // JDK1.7中已經不需要手工關閉這些資源了,JRE自動關閉這些資源。 // 一個對象實現了java.lang.AutoCloseable接口,或者是包含的所有對象實現了java.io.Closeable接口,即可以作為一個資源來使用。 String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path))) { return br.readLine(); } } @Test public void testAutoClose() throws Exception { String path = "D:\\TDDOWNLOAD\\readme.txt"; System.out.println(readFirstLineFromFileWithFinallyBlock(path)); System.out.println(readFirstLineFromFile(path)); }
7. 多個異常的合並與重拋異常的檢查
7.1 捕捉多個異常
看下面這段代碼:
catch (IOException ex) { logger.log(ex); throw ex; catch (SQLException ex) { logger.log(ex); throw ex; }
在JDK1.7中,上述代碼可以改寫為:
catch (IOException|SQLException ex) { logger.log(ex); throw ex; }
7.2 重拋異常
看下面這段代碼:
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; } }
在之前 JDK版本中,它不可以:throws FirstException, SecondException。而在JDK1.7中,它可以了,如下:
public void rethrowException(String exceptionName) throws FirstException, SecondException { try { // ... } catch (Exception e) { throw e; } }
注意:try/catch中throw的是Exception,但在函數頭中,卻是:throws FirstException, SecondException。這在之前的版本中編譯是通不過的。