Java SE 7是下一次JavaSE平台主要发布的版本。在正式发布之前,我们先关注一下这次Java在Java语言上有哪些改进。
在本文中,描述了Java SE 7 中Java语言的新特征。
在switch语句中使用String在JDK 7 发布版本中,开发人员可以在switch表达是中,使用String对象:
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; }
这次switch的增强,避免了遇到判断多个String对象时,使用多个if-else的表达式。try-with-resources语句try-with-resources语句是指在try语句中,描述了一个或多个资源资源的语句块,资源是指当程序结束后,必须关闭的资源对象。与try语句连用,确保接程序结束之前,每一个资源都被释放或关闭。任何实现了java.lang.AutoCloseable接口的可以作为一个资源使用。例如java.io.InputStream, OutputStream, Reader, Writer, java.sql.Connection, Statement, 和ResultSet,都实现了AutoCloseable接口,所有实现了这些接口的类都可以使用try-with-resources语句。考虑下面的例子,从文件中读取第一行。它会使用一个BufferReader的实例来从文件中读取数据。BufferReader是一个资源,当程序结束之前,必须确保被关闭,下面的例子中,不管try语句中,是否出现异常,使用finally语句块来确保BufferReader的实例被正常关闭。 static String readFirstLineFromFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { return br.readLine(); } finally { br.close(); } }
在使用JAVA SE 7后,可以使用下面的方式来完成同样的功能。static String readFirstLineFromFile(String path) throws IOException { try (BufferedReader br = new BufferedReader(new FileReader(path)){ return br.readLine(); } }
我们在try-with-resources语句中,可以定义多个资源文件。下面的例子是一个拷贝文件的静态方法。这个例子展示了在先前Java SE版本中如何释放两个资源:static 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(); } }
下面的例子通过使用try-with-resources语句实现了同样的功能。static void copy(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); } }
在例子中,包含了两个资源,可以看出处理起来相当繁琐,需要嵌套的使用try语句才可以完成。下面再给出使用try-with-resources语句自动关闭java.sql.Statement对象的例子:public static void viewTable(Connection con) throws SQLException { String query = "select COF_NAME, SUP_ID, PRICE, SALES, TOTAL from COFFEES"; try (Statement stmt = con.createStatement()) { ResultSet rs = stmt.executeQuery(query); while (rs.next()) { String coffeeName = rs.getString("COF_NAME"); int supplierID = rs.getInt("SUP_ID"); float price = rs.getFloat("PRICE"); int sales = rs.getInt("SALES"); int total = rs.getInt("TOTAL"); System.out.println(coffeeName + ", " + supplierID + ", " + price + ", " + sales + ", " + total); } } catch (SQLException e) { JDBCTutorialUtilities.printSQLException(e); } }
泛型接口的使用看下面一个泛型变量的例子:Map<String, List<String>> myMap = new HashMap<String, List<String>>();
在Java SE 7, 可以使用不带任何泛型参数的方式来构造一个泛型变量,例如: Map<String, List<String>> myMap = new HashMap<>();
再看一个错误使用的例子,下面的例子编译时会出错
List<String> list = new ArrayList<>(); list.add("A"); list.addAll(new ArrayList<>());
原因是因为list 定义的泛型是String,addAll方法指能接受addAll ArrayList<String>的实例。
捕获多个异常类型,使用改进的类型检查重新抛出异常处理多个异常类型在 Java SE 第 7 和更高的版本,一个 catch 块可以处理多个类型的异常。此功能可以降低代码重复,并减少捕捉异常过于宽泛的缺陷。请考虑下面的示例中,在每一个catch块中,都包含了重复的代码:
catch (IOException ex) { logger.log(ex); throw ex; catch (SQLException ex) { logger.log(ex); throw ex; } 在 Java SE 7 之前的版本,很难通过一个通用的方法消除重复的代码,因为变量前ex都有不同的异常类型。下面的示例中,在 Java SE 7 及更高版本中是可以使用的,可以消除重复的代码:
catch (IOException|SQLException ex) { logger.log(ex); throw ex; } catch 子句指定了需要捕获的所有异常类型,每种异常类型之间用 (|)隔开。
注: 如果 catch 块处理多个异常类型时,参会会被隐式的标记为final,在上面的例子中,ex 捕获参数是隐式的标记为final的,因此在catch块中,不能对ex重新赋值。
编译可以处理多个异常类型的 catch 块,比编译许多catch块生成的字节码较小,而且性能更好,编译的字节码中,也不会有重复代码。
用兼容性更强的类型检查重新抛出异常
Java SE 7 编译器对于重新抛出异常的处理上,比早期版本的 Java SE有更精确的分析。这使您能够在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 块可能抛出 FirstException 或 SecondException。假设您想要的 rethrowException 方法声明throw块中指定这些异常类型。在 Java SE 7 之前的版本,是不能这样做的。因为catch块的参数e,是Exception类型的,catch 块再次抛出的异常的参数 e、 只能通过在rethrowException 方法中指定throws块为Exception类型的异常。然而,在Java SE 7中,你可以在throws子句中,指定FirstException和SecondException的异常类型。Java SE 7编译器能判断出是最终抛出FirstException还是SecondException。即使异常参数e是Exception类型的:
public void rethrowException(String exceptionName) throws FirstException, SecondException { try { // ... } catch (Exception e) { throw e; } }
在数字定义中使用下划线在 Java SE 第 7 和更高的版本,可以数字的任何位置可以使用任意个的下划线字符 (_)。,可以提高代码的可读性。
例如,如果您的代码中包含很多位数的数字,你可以使用下划线分隔,类似于在句子中,使用都标点符号作为分隔符。
下面的示例显示在数字中使用下划线的方法:
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;
你只能将下划线放在数字之间的位置,你不能将下划线放在下面几个地方• 在数字开发不能放• 在小数点傍边不能使用下划线• 不能放在F或L 后缀之前 • 本该是非数字字符的位置上不能使用下划线。下面是一些非法和合法的例子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
参考文档
http://download.java.net/jdk7/docs/