接口中允许添加私有方法
java 8 中添加了 default 方法,但这些方法之间却无法优雅的复用代码。例如:methodA 和 methodB 都需要调用 biFunction 方法,于是只能将 biFunction 方法声明成 default。
public interface Java8Interface {
default void methodA(int a, int b) {
// do something
biFunction(a, b);
}
default void methodB(String a, String b) {
// do something
biFunction(a, b);
}
default void biFunction(Object a, Object b) {
// do something
}
}声明一个新的 default 方法当然可行,但却不符合接口的原则。将不必要的方法,暴露出去会给调用者带来困扰。
public interface Java9Interface {
default void methodA(int a, int b) {
// do something
biFunction(a, b);
}
default void methodB(String a, String b) {
// do something
biFunction(a, b);
}
private void biFunction(Object a, Object b) {
// do something
}
}允许私有方法后,只需把原来的 default 改成 private 即可。
try-with-resource 优化
Java 7 之前关闭资源需要写如下代码:
BufferedReader br = new BufferedReader(...);
try {
return br.readLine();
} finally {
if (br != null) {
br.close();
}
}Java 7 之后引入了 try-with-resource ,简化了 finally 块的代码,现在只需这样:
try (BufferedReader br = new BufferedReader(...)) {
return br.readLine();
}但是需要使用的资源一多,代码就会变成这样:
try (BufferedReader br1 = new BufferedReader(...);
BufferedReader br2 = new BufferedReader(...);
BufferedReader br3 = new BufferedReader(...)) {
return br1.readLine() + br2.readLine() + br3.readLine();
}Java 9 之后:
BufferedReader br1 = new BufferedReader(...);
BufferedReader br2 = new BufferedReader(...);
BufferedReader br3 = new BufferedReader(...);
try (br1; br2; br3) {
return br1.readLine() + br2.readLine() + br3.readLine();
}注意:变量声明在 try 外面,很容易误导用户在 try 语句结束后,仍调用资源,这会导致运行时产生错误。
BufferedReader br1 = new BufferedReader(...);
try (br1) {
System.out.println(br1.readLine());
}
br1.readLine(); // 此时资源已关闭,调用会报错_ 不再是有效标识符
Java 9 之前可以将 _ 下划线设置为变量,虽然编译器会警告,但运行不会报错。
int _ = 123;
System.out.println(_);Java 9 之后,代码会编译失败,会得到如下提示:
java: 从发行版 9 开始, '_' 为关键字, 不能用作标识符菱形符号
Java 7 引入了菱形符号 <>,让编译推断构造器参数类型。
// java 7 之前
List<String> names = new ArrayList<String>();
// java 7 之后
List<String> names = new ArrayList<>();自动参数类型推断,简化了代码。但是匿名内部类的参数推断,却不支持。
这段代码在 Java 7 中,编译器会报错。Java 9 支持匿名内部类的类型推断,代码能正确执行。
<T> Result<T> create(T content) {
return new Result<>(content) {
// 实现方法
};
}