Java7发布有一段时间了,这几天升级了一下JDK,结果发现Eclipse3.7还没有支持JDK7。这个需要稍微解释一下,可能有人不知道,Eclipse使用自己的Java编译器而不是JDK自带的javac。Eclipse自己的编译器就是ecj(Eclipse Compiler for Java),一般的Linux发行版都有eclipse-ecj这样的包。ecj其实也是用Java实现的,编译出来的class文件比javac小一点,按照使用Eclipse的经验来看,ecj编译速度也比javac快一些。PS:最新的Eclipse开发版已经支持JDK7了。
虽然闭包、python样式的集合和null安全语法这些非常酷的特性被延期到了Java8,Java7中还是有其他一些很不错的新语言特性。首先是两个数值表述语法上的改进:支持以0b开头的二进制数值(Binary Literals);和支持在数值中包含下划线(Underscores in Numeric Literals)。
class Main
{
public static void main(String[] args)
{
int a = 157;
int b = 0b1001_1101;
int x = 0x9d;
System.out.println(a == b);
System.out.println(a == x);
}
}
Switch语句支持字符串(Strings in switch Statements):
class Main
{
public static void main(String[] args)
{
switch(args[0])
{
case "start":
System.out.println("Started!");
break;
case "stop":
System.out.println("Stopped!");
break;
}
}
}
自动推断泛型参数(Type Inference for Generic Instance Creation)。下面的例子中,第一条语句是JDK7之前的规范而冗长的语法,第二条是JDK7新增的自动类型推断语法,第三条无论是JDK7还是之前的版本都会给出一个warning。
Map<String, List<String>> myMap = new HashMap<String, List<String>>();
Map<String, List<String>> myMap = new HashMap<>();
Map<String, List<String>> myMap = new HashMap();
对于try...catch结构有两个改进,第一个是支持单语句捕获多个类型的异常(Catching Multiple Exception Types)。下面的例子中,第一段代码是JDK7之前冗长的catch列表;第二段代码是JDK7新语言特性带来的清爽。
class GoodException extends Exception {}
class BadException extends Exception {}
class Main
{
public static void main(String[] args)
{
try
{
if(args.length == 0)
throw new GoodException();
else
throw new BadException();
}
catch(GoodException e)
{
e.printStackTrace();
}
catch(BadException e)
{
e.printStackTrace();
}
}
}
class GoodException extends Exception {}
class BadException extends Exception {}
class Main
{
public static void main(String[] args)
{
try
{
if(args.length == 0)
throw new GoodException();
else
throw new BadException();
}
catch(GoodException | BadException e)
{
e.printStackTrace();
}
}
}
第二个对于try...catch结构的改进是类似C#的using语句(The try-with-resources Statement),在try语句中打开的资源会自动释放,无论是正常退出还是异常退出。这要求打开的资源必须实现AutoClosable接口或者Closable接口。JDK7里的IO类都实现了AutoClosable接口。同样给出两段代码以作比较:
import java.io.*;
class Main
{
public static void main(String[] args) throws IOException
{
String data = "hello";
ByteArrayOutputStream out = null;
try
{
out = new ByteArrayOutputStream();
out.write(data.getBytes());
System.out.println(new String(out.toByteArray()));
}
catch(IOException e)
{
e.printStackTrace();
}
finally
{
if(out != null)
out.close();
}
}
}
import java.io.*;
class Main
{
public static void main(String[] args)
{
String data = "hello";
try(ByteArrayOutputStream out = new ByteArrayOutputStream())
{
out.write(data.getBytes());
System.out.println(new String(out.toByteArray()));
}
catch(IOException e)
{
e.printStackTrace();
}
}
}
这几个新特性大部分还是很有用的,尤其是对try...catch结构的改进。由于Java的严谨性,try...catch可谓无处不在,本来很短的代码,套上try...catch之后就变得很长,有了这两项对症下药的改进,可以大大缩减代码量。