Java 8 之后,还有哪些进化的功能?
作者 | Dávid Csákvári
译者 | 弯月,责编 | 郭芮
出品 | CSDN(ID:CSDNnews)
https://advancedweb.hu/2019/02/19/post_java_8/
var greetingMessage = "Hello!";
尽管看上去这很像JavaScript的var关键字,但它并不是动态类型。
我们希望通过减少编写Java代码时的繁文缛节来改善编程的体验,同时维持Java的静态类型安全。
MyAwesomeClass awesome = new MyAwesomeClass();
var date = LocalDate.parse("2019-08-13");
var dayOfWeek = date.getDayOfWeek();
var dayOfMonth = date.getDayOfMonth();
做完了?答案如下所示。
private void horriblyLongMethod() {
// ...
// ...
// ...
var dayOfWeek = date.getDayOfWeek();
// ...
// ...
// ...
}
有了上一个例子的经验,我打赌你肯定会猜它是java.time.DayOfWeek。但这次是个整型,因为本例中的date是Joda时间。这是个不同的API,行为也略有不同,但你没有发现,因为这个方法非常长,而你并没有阅读所有代码。
Map<String, String> myMap = new HashMap<String, String>(); // Pre Java 7
Map<String, String> myMap = new HashMap<>(); // Using Diamond operator
由于该运算符只处理泛型类型,所以我们依然可以去掉一些冗余。我们可以通过var进一步简化:
var myMap = new HashMap<>();
这个例子是合法的,而且Java 11编译器甚至都不会发出警告。但是,我们没有为泛型类型指定任何类型,导致所有类型都必须推断,所以最后的类型是Map<Object, Object>。
var myMap = new HashMap<String, String>();
另一个问题是在基本数据类型上使用var:
byte b = 1;
short s = 1;
int i = 1;
long l = 1;
float f = 1;
double d = 1;
如果不给出显式类型定义,那么所有变量都会被推断为int。所以,使用基本数据类型时要使用类型字面量(例如1L),或者不要使用var。
与Java 10的var的第一次亲密接触(https://blog.codefx.org/java/java-10-var-type-inference/)
Java局部变量类型推断详解(https://dzone.com/articles/var-work-in-progress)
Java 10:局部变量推断(https://www.journaldev.com/19871/java-10-local-variable-type-inference)
菱形运算符
try-with-resources语句
多catch和更精确的重新throw
在switch语句中使用字符串
二进制整形字面量和数值字面量中的下划线
简化的varargs方法调用
List<Integer> numbers = new ArrayList<>();
但是,以前该功能不能用于匿名内层类上。根据项目的邮件列表中的讨论(http://mail.openjdk.java.net/pipermail/coin-dev/2011-June/003283.html)可知,该功能没有作为菱形运算符的最初特性实现的原因是它需要JVM做出重大变更。
List<Integer> numbers = new ArrayList<>() {
// ...
}
BufferedReader br = new BufferedReader(...);
try {
return br.readLine();
} finally {
if (br != null) {
br.close();
}
}
try (BufferedReader br = new BufferedReader(...)) {
return br.readLine();
}
try (BufferedReader br1 = new BufferedReader(...);
BufferedReader br2 = new BufferedReader(...)) {
System.out.println(br1.readLine() + br2.readLine());
}
而且,在Java 7之前,如果你想用这种写法来处理已有的变量,就必须定义一个临时变量。(例如JDK-8068948中的例子:https://bugs.openjdk.java.net/browse/JDK-8068948。)
BufferedReader br1 = new BufferedReader(...);
BufferedReader br2 = new BufferedReader(...);
try (br1; br2) {
System.out.println(br1.readLine() + br2.readLine());
}
在这个例子中,变量初始化不需要跟try-with-resources的初始化部分写在一起。
BufferedReader br = new BufferedReader(...);
try (br) {
System.out.println(br.readLine());
}
br.readLine(); // Boom!
int _ = 10; // Compile error
【END】
技术人在关注TA!戳↓↓↓
热 文 推 荐
☞ 重磅!全球首个可视化联邦学习产品与联邦pipeline生产服务上线
☞ 语音识别技术简史