一、switch语句可以使用字符串匹配,之前只能使用与整数类型兼容的类型,包括char byte short和int ,与对应的封装类 Character Byte Short和Integer
public class Title{
public string generate(String name, String gender){
String title = "";
switch (gender){
case "男":
title = name + "先生";
break;
case "女":
title = name + "女士";
break;
default:
title = name;
}
return title;
}
}
实现原理: 如果是一个或两个case,编译时转换为 if else, 如果是多个case , 把字符串取哈希。JVM和字节代码上,还是只支持使用与整数类型兼容的类型。
注意:虽然以后switch可以用字符串判断,但是碰到多个枚举值选择的时候,还是推荐java 5中增加的,用 enum 声明枚举值。
二、数值字面量改进
二进制字面量,过去只支持十进制,八进制(0)和十六进制(0x)
import static java.lang.System.out; //静态导入
...
out.println(0b001001) //输出9
out.println(0B001110) //输出11
二进制字面量,使得在源代码中使用二进制数据更加简单。
在数值字面量中使用下划线
日常生活习惯把 600000,写成600,000,方便分辨数字的位数。
java允许引入类似表达方式,不过只是 下划线 而已。
out.println(1_500_000) // 1500000
double value1 = 5_6.3_4 // 56.34
int value2 = 89_3__1; //8931
注:下划线前后都必须是数字,_100, 120_, 0b_101, 0x_da0, 均不可。
三、优化异常处理
1
非受检异常: java.lang.RuntimeException和java.lang.Error类及其子类
受检异常:所有其他异常
非收检异常可以去掉一些不需要的异常处理代码,但是开发人员可能忽略某些应该处理的异常,比如字符串转数字时发生java.lang.NumberFormatException.
受检异常对程序中的设计提出更高的要求,但不恰当使用会充斥大量没有实际作用只为编译通过的代码。
主流意见:优先使用非受检异常。
2
异常作为API的一部分公开后,不宜修改,否则使用API的代码会编译错误,需要谨慎设计。
3、自定义异常, 继承自Exception。
异常需要根据层次结构细分,在不同的抽象层次上定义相关的异常。
比如服务端调用数据访问代码,只关心数据访问可能出现异常即可,不关心是数据库访问异常,还是文件系统访问异常。
public class DataAccessGateway{
public void load() throws DataAccessException{
try{
FileInputStream input = new FileInputStream("data.txt");
}catch(IOException e){
throw new DataAccessException(e);
}
}
}
4、处理异常
try catch finally后,finally中再出现异常,被捕获后throws,外层只能看到finally中的,看不到try中最开始的异常,造成错误的判断
FileInputStream input = null;
IOException readException = null;
try{
input = new FileInputStream(filename);
}catch(IOException ex){
readException = ex;
} finally{
if(input != nul){
try{
input.close();
}catch(IOExeption ex){
if(readException !=null){
readException.addSuppressed(ex); // 7 中为Throwable类增加的addSuppressed方法,被放入异常的堆栈信息中
}else{ // 通过getSuppressed方法获得这些异常
readException = ex;
}
}
}
if(readException != null){
throw readException;
}
}
5、Java7的异常处理新特性
一个catch子句捕获多个异常
public class ExceptionHandler{
public void handle(){
ExceptionThrower thrower = new ExceptionThrower();
try{
thrower.manyExceptions(): //这里 A可以是B的子类,但反之不可
}catch(Exception A | Exectpion B ab){//用 | 号分割,如果A和B处理逻辑一样,就可以放一起
}catch(Exception C c){
}
}
}
实现:编译器又改回了多个catch (catch A , catch B, catch C),
6、try-with-resources语句
try(BufferedReader reader = new BufferedReader(new FileReader("data.txt"))){//资源申请
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语句异常,释放资源OK,则跑出try语句中的异常
如果try语句异常,释放资源也异常,同样抛出try语句中的异常,释放资源异常会作为被抑制的异常添加进去,即Throwable.addSuppressed方法来实现。
使用:
实现java.lang.AutoCloseable接口的类,才能使用try 资源管理语句。
与IO相关的java.io.Closeable继承了AutoCloseable, 而同样的还有 java.sql.Connection、java.sq.ResultSet和java.sql.Statement。
可以对多个资源进行管理
try(Input Stream 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);
}
}
注:在try-with-resource语句中,也可以使用catch和finally子句, 在catch子句中捕获try语句块和释放资源时可能发生的各种异常。
四、优化边长参数的方法调用
java5引入了变长参数方法
public int sum(int... args){
int result = 0;
for(int value : args){
result += value;
}
return result;
}
public static <T> T useVarargs(T... args){
return args.lengt>0? args[0]:null;
}
如果参数是不可具体化的类型,如List<String>这样的泛型,每次调用都会产生警告
过去唯一的办法是用@SuppressWarnings("unchecked")
现在可以在方法签名上加上@SafeVarargs
@SafeVarargs //只能用在参数长度可变的方法或构造方法,且方法必须为static 或 final
public static <T> T useVarargs(T... args){
return args.length > 0 ? args[0] : null;
}
注:使用该注解,请确保该方法的实现对泛型类型参数的处理不会引发类型安全问题。