java7发布时,大多数开发人员都关注与新的语言特性,有一些被更改了的API很少被人发现,但在我们的日常工作中却使用比较频繁。
1、异常处理改进
a、try-with-resource语句
java7提供了一个简单、实用的代码格式如下:
打开一个资源
try{
使用该资源
}finally{
关闭该资源
}
其中资源所属的类必须实现了AutoCloseable接口。该接口只有一个方法:
void close() throws Exception
改进后的处理方式可以写成如下的形式:
try(Resource res = ...){
使用res
}
当try语句块退出时,会自动调用res.close()方法。try-with-resource语句自己也可以含有cath和finally分支。它们都会在关闭资源后执行。在实践中,不建议在单个try语句中放置太多的逻辑代码。
b、忽略异常
无论何时使用输入或者输出,在产生异常后如何关闭资源都是一个麻烦的问题。假设产生了一个IOException,接下来在关闭资源时,close方法又抛出了另一个异常。那么实际上会捕获哪个异常呢?在java中,finally分支中抛出的异常会丢弃到之前的异常。这不仅听上去不合理,实际上也确实不太合理。毕竟,用户对原始的异常会更感兴趣。
try-with-resource语句修改了这个行为。当AutoCloseable对象的close方法抛出异常时,原来的异常会被重新抛出,而调用close方法产生的异常会被捕获,并被标注为“被忽略”的异常。
c、捕获多个异常
在javase7中,你可以在同一个catch分支中捕获多个异常类型。捕获多个异常不仅能让你的代码看起来更简洁,而且效率也更高。生成的字节码会包含一个含有共享catch分支的代码块。
当捕获多个异常时,异常变量会被隐式设置为final类型。
2、实现equals、hashCode和compareTo方法
a、安全的null值相等测试
在java7之后,提供了Objects。equals(a,b)方法,如果a和b都是null,返回true;如果只有其中一个为null,返回false;其他情况返回a.equals(b)。从使用习惯和代码的规范性上讲,应该讲之前使用的a.equals(b)的地方更改为这种方式。
b、计算哈希码
对于null,Objects.hashCode方法会返回0。java7中引入的可变参数方法Objects.hash允许你指定任意个对象,并且它们的哈希码会被自动组合起来。
c、比较数值类型对象
当通过比较器来比较整型值时,因为允许返回任意负值或正值,所以它会试图返回二者之间相差的大小,但是实际上只需要知道符号就足够了。
在java7之后,可以使用静态方法Integer.compare来实现。过去,有开发人员会用new Integer(x).compareTo(other.x)的方式,但是这会创建两个会自动装箱/拆箱的整型对象。相比之下,静态方法compare使用的是int参数。此外,Long、Short、Byte和Boolean也都提供了各自的静态方法compare。如果你需要比较两个字符型值(char),可以直接将它们相减,结果不会溢出。Double和Float中的静态方法compare从java1.2开始就存在了。
3、其他改动
a、将字符串转换为数字
在jdk7之前,下面的代码的结果是什么
double x = Double.parseDouble("+1.0");
如果你知道结果,应该给自己一点奖励:+1.0一直都表示一个有效的浮点数,但是在java7之前,+1一直不是一个有效的整数。这个问题已经在所有通过字符串来构造int、long、short、byte和BigInteger的方法中被修复了。
b、全局Logger
为了鼓励在一些简单的程序中使用日志框架,Logger类现在提供了一个全局的Logger实例。因为它为了尽可能的简化使用,所以你可以在任何时候都使用Logger.global.finest("x=" + x);来代替System.out.println("x" + x);。
java7中提供了一直更简单的形式——Logger.getGlobal()。
c、Null检查
Objects类提供了requireNonNull方法以便于检查参数是否为null。