那些年我错过的java

最近在看面向对象设计的书,有了一些新的感悟。于是周末闲来无事,想写个小东西练练手。最近一直用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**
  1. Automated Resource Management
  2. Timsort is used to sort collections and arrays of objects instead of merge sort
  3. Multiple exceptions handling in single catch block
  4. String in switch
  5. JDBC 4.1 support
  6. JVM Enhancements(invokedynamic instructions)
  7. Automatic Type Inference during the Generic Instance Creation(using diamond operator)
  8. Numeric literals with underscore
  9. Fork and Join Framework
  10. G1 Garbage Collector
**JDK 1.8 Code Name : Spider Year : 2014**
  1. Lambda Expression
  2. Streams
  3. Functional Interface
  4. Nashorn
  5. Performance Improvement for HashMaps with Key Collisions
  6. Parallel Array Sorting
  7. StringJoiner class
  8. Optional class
  9. Remove permanent generation
  10. Annotation on Java Types
**JDK 1.9 Code Name : Jigsaw Year : 2017**
  1. JShell: the interactive Java REPL
  2. Private interface methods
  3. Process API Updates
  4. Light-Weight JSON API
  5. Money and Currency API for representing, transporting, and performing comprehensive calculations with Money and Currency
  6. Segmented Code Cache
  7. Improve Contended Locking