前言
Java7,代号「海豚(Dolphin)」,是 Java 历史上一次非常重大的版本更新,同时也是我入门学习 Java 所用的版本。本篇主要介绍几个很实用的 Java7 特性,文中若有用词不当或专业术语不准的现象,望见谅!
Java7 新特性:
1.二进制形式的字面值表示
2.在数值类型的字面值中使用下划线分隔符联接
3.创建泛型实例时自动类型推断
4.switch-case 语句支持字符串类型
5.新增 try-with-resources 语句
6.单个 catch 子句同时捕获多种异常类型
7.引入 java.util.Objects 工具类
二进制形式的字面值表示
由于继承 C 语言,Java 代码在传统上迫使程序员只能使用十进制,八进制或十六进制来表示数 (numbers)。Java SE 7 中,整数类型(byte、short、int 以及 long) 也可以使用二进制数系来表示。要指定一个二进制字面量,可以给二进制数字添加前缀 0b 或者 0B。
1 | // 一个 8 位的'byte'值: |
支持的数字字面量表示:
十进制:默认的
八进制:整数之前加数字 0 来表示
十六进制:整数之前加 “0x” 或“0X”
二进制(新加的):整数之前加 “0b” 或“0B”
在数值类型的字面值中使用下划线分隔符联接
如果 Java 源代码中有一个很长的数值字面量,开发人员在阅读这段代码时需要很费力地去分辨数字的位数,以知道其所代表的数值大小。在现实生活中,当遇到很长的数字的时候,我们采取的是分段分隔的方式。比如数字 500000,我们通常会写成 500,000,即每三位数字用逗号分隔。利用这种方式就可以很快知道数值的大小。这种做法的理念被加入到了 Java7 中,不过用的不是逗号,而是下划线“_”。
1 | // 输出 56.34 |
注意:下划线只能出现在数字中间,前后必须是数字。所以“_100”、“0b_101“是不合法的,无法通过编译。
创建泛型实例时自动类型推断
只要编译器从上下文中能够推断出类型参数,你就可以使用一个空的类型参数集合 (<>) 代替调用一个泛型类的构造器所需要的类型参数。这对尖括号通常叫做 diamond。
1 | // 举个例子, 考虑下面的变量声明: |
注意:想要在泛型类初始化期间利用自动类型推断,你必须要指定 diamond。这个 <> 被叫做 diamond(钻石)运算符,Java 7 后这个运算符从引用的声明中推断类型。
switch-case 语句支持字符串类型
switch 语句可以使用原始类型或枚举类型。Java 引入了另一种类型,我们可以在 switch 语句中使用:字符串类型。
1 | String input = "Monday"; |
新增 try-with-resources 语句
Java 中某些资源是需要手动关闭的,如 InputStream,Writes,Sockets,Sqlclasses 等。这个新的语言特性允许 try 语句本身申请更多的资源,这些资源作用于 try 代码块,并自动关闭。
1 | // 传统的资源关闭方式[为了确保外部资源一定要被关闭, 通常关闭代码被写入 finally 代码块中, 当然我们还必须注意到关闭资源时可能抛出的异常] |
那什么是 try-with-resource 呢?简而言之,当一个外部资源的句柄对象(比如 FileInputStream 对象)实现了 AutoCloseable 接口,将外部资源的句柄对象的创建放在 try 关键字后面的括号中,当这个 try-catch 代码块执行完毕后,Java 会确保外部资源的 close 方法被调用。
单个 catch 子句同时捕获多种异常类型
在 Java7 中,catch 代码块得到了升级,用以在单个 catch 块中处理多个异常。如果你要捕获多个异常并且它们包含相似的代码,使用这一特性将会减少代码重复度。
1 | // Java 7 之前的版本: |
引入 java.util.Objects 工具类
引入 java.util.Objects 工具类,用于封装一些平时使用频度很高或容易出错的操作。
(1)Objects.equals(Object a, Object b):有别于 Object.equals(Object a, Object b),这个方法可以避免空指针异常。
1 | public static boolean equals(Object a, Object b) { |
(2)Objects.deepEquals(Object a, Object b):Object.equals(Object a, Object b) 用于比较两个对象的引用是否相同,而 deepEquals() 却扩展成了可以支持数组。
1 | public static boolean deepEquals(Object a, Object b) { |
(3)Objects.hashCode(Object o):和 Object.hashCode(Object o) 类似,只是在对象为 null 时返回的散列值为 0 而已。
1 | public static int hashCode(Object o) { |
(4)Objects.hash(Object… values):生成对象的散列值,包括数组。
1 | public static int hash(Object... values) { |
(5)Objects.toString(Object o):归根结底,其内部最终调用了对象的 toString() 方法。只是额外多了空指针判断而已。
1 | public static String toString(Object o) { |
(6)Objects.compare(T a, T b, Comparator< ? super T> c):用于比较两个对象。
1 | public static <T> int compare(T a, T b, Comparator<? super T> c) { |
(7)Objects.requireNonNull(T obj):在对象为空指针时,抛出特定 message 的空指针异常。
1 | public static <T> T requireNonNull(T obj) { |
(8)Objects.isNull(Object obj) / Objects.nonNull(Object obj):这两个方法用于判断对象为 null 和对象不为 null。通常情况下,我们不会直接使用这两个方法,而是使用比较操作符 == 和 !=。这两个方法主要用在 jdk8 开始支持的流计算里面。
1 | public static <T> T requireNonNull(T obj) { |