那些年我错过的java
07 Jul 2018最近在看面向对象设计的书,有了一些新的感悟。于是周末闲来无事,想写个小东西练练手。最近一直用Python,所以想回归一下更OO一些的Java。正研究怎么升级到Java 9尝尝鲜,结果发现再有80天Java 11都要发布了!真是山中方一日,世上已千年。才不关注Java没多久,已经快成版本帝了。索性直接上了Java 10,把最近落下的都补上。在这个夏天,补上那些年我错过的Java。
在开始之前要做的当然就是升级到最新版本,这是在Linux(Mint)上通过PPA的方式安装最新版本Java的命令:
$ sudo add-apt-repository ppa:linuxuprising/java
$ sudo apt update
$ sudo apt install oracle-java10-installer
$ sudo apt install oracle-java10-set-default
本文所有例子都可以加入测试类Test,并编译运行javac Test.java && java Test。当然,也可以玩一下Java 9提供的JShell,通过/set feedback verbose在每条命令后能够看到更多信息。
public class Test {
public static final void main(String[] args) {
//...
}
}
1.语言特性增强
1.1 类型推断
Java很恼人的一点就是泛型,的确强制声明类型更加严谨和安全。然而在构建复杂数据类型时,代码会变得非常丑陋。Java 7试图改善这一问题,允许我们省略具体类型而让编译器自己去推断,还很形象地为其取名叫做Diamond Operator(钻石操作符)。
Map<String, List<String>> employeeGroupByAge = new HashMap<>();
Java 10中又进一步地让编译器变得更加聪明,引入了var关键字,让编译器自动推断本地变量的类型。
var employeeGroupByAge = new HashMap<>();
employeeGroupByAge.put(25, List.of("Allen", "Hank"));
employeeGroupByAge.put(30, List.of("Carter"));
System.out.println(employeeGroupByAge); //{25=[Allen, Hank], 30=[Carter]}
从下面JShell的输出可以看出,Java已经足够聪明了,能够推断出甚至比人为声明更为精细的类型。
jshell> var list = List.of(1, 2.0, "3");
list ==> [1, 2.0, 3]
| modified variable list : List<Serializable&Comparable<? extends Serializable&Comparable<?>>>
| update overwrote variable list : List<Serializable&Comparable<? extends Serializable&Comparable<?>>>
1.2 字符串
Java 7中很实用的一个特性就是Switch也支持字符串了,之前我们只能通过大段的if-then-else来实现。而且据说Switch更利于编译器做优化,具体为什么还要研究一下。
switch (type) {
case "Hello": System.out.println("Hi!"); break;
case "World": System.out.println("Wow!"); break;
default: System.out.println("Bye!"); break;
}
此外一个小的改进就是String的Join,听起来好像Java太落后了…… 其实改进后依然与Python甚至Apache Lang中提供的工具方法有不小的差距。
System.out.println(new StringJoiner("+", "prefix+", "+suffix").add("a").add("b").add("c"));
System.out.println(String.join("+", "prefix", "a", "b", "c", "suffix"));
System.out.println(String.join("+", List.of("prefix", "a", "b", "c", "suffix")));
1.3 异常处理
Java 7中提供了几个非常实用的异常处理的语法特性,比如自动资源管理。第一次见到这个特性还是在大概十年前初学C#时,印象里好像是use关键字。Java沿用了try关键字,取名叫try-with-resources语句。但基本思想上是一样的,都是为了省去finally里无聊的资源关闭代码。适用于各种常见的资源,比如Connection、File、Stream等。
try (FileInputStream f = new FileInputStream("test.txt")) {
//...
}
Socket s1 = ...;
File f1 = ...;
try (s1; f1) {
//...
}
那其他资源或者我们自己的资源类呢?其实这些资源类都实现了java.lang.AutoCloseable接口,所以我们也可以实现它来获得自动关闭的能力。最近Java 9中又进一步简化,可以在try中传入多个final变量,甚至可以是不同的资源类型,只要它们实现了AutoCloseable接口即可。
在一个Catch中可以捕获多种异常,提供统一的处理和恢复逻辑,从而减少重复代码。
try {
//...
} catch (FileNotFoundException | IOException ex) {
ex.printStackTrace();
}
1.4 面向对象
interface
optional
2.新库函数引入
2.1 NIO 2
2.2 JodaTime
JSON
货币
HTTP/2 Client
3.多语言风格融合
3.1 REPL
REPL (Read-Evaluate-Print-Loop)
2.1 动态
2.2 Nashorn JS引擎
2.2 Lambda
2.1 Fork-Join框架(Java 7)
2.2
4.JVM
3.1 InvokeDynamic指令(Java 7)
4.2 永久代的移除(Java 8)
3.1 G1成为默认GC(Java 9)
在Java 7首次引入的垃圾回收器G1,在经历了几代的谨慎实验后,在Java 9中终于成为默认的GC。
附录:Release
引自Quora问答回帖:https://www.quora.com/What-are-the-differences-between-Java-6-Java-7-Java-8-and-Java-9
| **JDK 1.7 | Code Name : Dolphin | Year : 2011** |
- Automated Resource Management
- Timsort is used to sort collections and arrays of objects instead of merge sort
- Multiple exceptions handling in single catch block
- String in switch
- JDBC 4.1 support
- JVM Enhancements(invokedynamic instructions)
- Automatic Type Inference during the Generic Instance Creation(using diamond operator)
- Numeric literals with underscore
- Fork and Join Framework
- G1 Garbage Collector
| **JDK 1.8 | Code Name : Spider | Year : 2014** |
- Lambda Expression
- Streams
- Functional Interface
- Nashorn
- Performance Improvement for HashMaps with Key Collisions
- Parallel Array Sorting
- StringJoiner class
- Optional class
- Remove permanent generation
- Annotation on Java Types
| **JDK 1.9 | Code Name : Jigsaw | Year : 2017** |
- JShell: the interactive Java REPL
- Private interface methods
- Process API Updates
- Light-Weight JSON API
- Money and Currency API for representing, transporting, and performing comprehensive calculations with Money and Currency
- Segmented Code Cache
- Improve Contended Locking