JDK1.7新特性

1. 二进制文本

在jdk1.7之前,所支持的进制包括十进制、八进制和十六进制。八进制在数字字面量前面添加0来表示,十六进制在数字字面量前面添加0x来表示。如果要处理二进制值,就必须进行基础的转换,或者调用parseX方法。如:想让int x变量用位模式(计算机中所有二进制的0、1代码所组成的数字串)表示十进制值102,可以这样写:

int x = Integer.parseInt("1100110", 2);
在jdk1.7中,byte、short、int、long的位模式表示法就是在位模式的前面添加前缀0b或0B,如下显示二进制文本:

// 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;

2. 在数字字面量中使用下划线

在jdk1.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;
注意数字字面量中的下划线只能出现在数字中间,也就是说前后都是数字。其他写法都是非法的。

3. 在switch中使用字符串

在jdk1.7之前,switch中的条件表达式的类型只能是Char、Byte、Short、Integer和Enum类型。在jdk1.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;

4. 泛型实例的类型推断

在jdk1.7之前,创建一个泛型类型的对象总是需要显式指定实际的类型,泛型类型声明在构造方法的类型声明和创建的对象的引用类型声明中同时出现,如:

Map<String, List<String>> myMap = new HashMap<String, List<String>>();
在jdk1.7中对这个对象创建形式进行了简化,在调用构造方法时不需要显式声明类型,直接使用“<>”来代替,具体的类型通过对象引用的类型来进行推断,如:

Map<String, List<String>> myMap = new HashMap<>();

5. 优化可变参数的方法调用

jdk5.0中在方法声明中引入了可变参数,在调用时这些参数以数组的形式来调用。在jdk1.7之前如果可变参数是不可具体化类型时,如List<String>,编译器会产生警告信息。这其中的原因是可变参数的实际值是通过数组来传递的,而数组中存储的是不可具体化的泛型类对象,自身存在类型安全问题。因此编译器会给出警告信息(禁止这个警告可用@SuppressWarnings("unchecked")注解)。
为了解决这个问题,jdk1.7中引入了@SafeVarargs注解,如下:
@SafeVarargs
public static <T> void addToList3 (List<T> listArg, T... elements) {
    for (T x : elements) {
      listArg.add(x);
    }
}
@SafeVarargs注解只能用在可变参数的方法或构造函数上,且方法必须是static或final,否则出现编译错误。使用@SafeVarargs的前提是开发人员必须确保这个方法的实现对泛型类型参数的处理不会引发类型安全问题。

6. try-with-resources语句

在读取磁盘文件、访问数据库等资源时都有可能抛出各种异常,而资源管理不管操作是否成功,所申请的资源都要被正确释放。之前可以通过try-catch-finally的finally语句块来释放资源操作。
为了简化这种操作,jdk1.7对try语句进行了增强,它支持对资源进行管理,保证资源正确释放,如下代码所示:

public String readFile(String filename) throws IOException {
	try (BufferedReader reader = new BufferedReader(new FileReader(filename))) {
		StringBuilder builder = new StringBuilder();
		String line = null;
		while ((line = reader.readLine()) != null) {
			builder.append(line);
			builder.append(String.format("%n"));
		}
		return builder.toString();
	}
}
以上代码不需要finally来释放资源,资源的申请是在try子句中进行的,而资源的释放则是自动完成的。能够被try管理的资源需要满足一个条件,就是资源类必须实现java.lang.AutoCloseable接口,一般的文件、数据库连接等均已实现该接口,close方法将被自动调用。
try-with-resources还可以对多个资源进行管理,如:

public void copyFile(String fromPath, String toPath) throws IOException {
	try (InputStream input = new FileInputStream(fromPath);
		OutputStream output = new FileOutputStream(toPath)) {
		byte[] buffer = new byte[8192];
		int len = 1;
		while((len = input.read(buffer)) != -1){
			output.write(buffer, 0, len);
		}
	}
}

7. 异常处理改善

在jdk1.7之前的异常出路语句中,一个catch子句只能捕获一个异常类,如:
catch (IOException ex) {
     logger.log(ex);
     throw ex;
catch (SQLException ex) {
     logger.log(ex);
     throw ex;
}
对于这种情况,jdk1.7改进了catch子句的语法,允许在其中指定多个异常类,每个异常类之间用“|”来分割。如下:
catch (IOException|SQLException ex) {
    logger.log(ex);
    throw ex;
}
在进行异常处理的时候,如果当前代码无法处理异常,应该把异常重新抛出,交由上层代码来处理。jdk1.7对重新抛出异常时的异常类型做了更加精确的判断,保证异常的确可以正常抛出,可以抛出大于声明的异常类型,如下:
static class FirstException extends Exception { }
static class SecondException extends Exception { }

public void rethrowException(String exceptionName)
throws FirstException, SecondException {
    try {
      // ...
    }
    catch (Exception e) {
      throw e;
    }
}



发布了7 篇原创文章 · 获赞 4 · 访问量 2万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章