2022-03-21
Java 平台自出现到目前为止,已经 20 多个年头了,这 20 多年间 Java 也一直作为最流行的程序设计语言之一,不断面临着其他新兴编程语言的挑战与冲击。Java 语言是一种静态强类型语言,这样的语言特性可以让 Java 编译器在编译阶段发现错误,这对于构建出一个稳定安全且健壮的应用来说,尤为重要。但是也因为这种特性,让 Java 开发似乎变得缺少灵活性,开发某些功能的应用时,代码量可能是其他语言的几倍。Java 开发的不足之处也体现越来越复杂的 JDK 上,越来越复杂的 JDK 让开发者完全理解的难度变的非常大。以至于开发者有时会重复实现一个 JDK 中已经提供了的功能。
为了跟上互联网应用编程发展的脚步, Java 从 9 版本开始调整了 JDK 发布的节奏,JDK 的每次更新都注重提高生产效率,提高 JVM 性能,推行模块化等,让开发者可以更多的专注于业务本身,而不是浪费过多的时间在语言特性上。 Java 语言的更新要在语言的严谨性和灵活性上找到一个平衡点,毕竟灵活性可以减少编码的复杂度,而严谨性是构建复杂且健壮应用的基石。
Java 重要的更新版本是在 Java 5 版本,这个版本中增加了如泛型、增强 for、自动装箱拆箱、枚举类型,可变参数、注解等一系列重要功能,但是随后的 Java 6 中并没有增加新的重要的语言特性。Java 5 的发布是在 2004 年,已经很久远了,网上关于 Java 的教程也大多是基于 Java 6 的,也因此我准备从 Java 7 开始介绍每个 Java 版本的新特性。
下面所有代码的运行演示都是基于 Java 7 ,所以你如果尝试下面的代码,需要安装并配置 Jdk 1.7 或者已上版本。
在 Java 7 之前,switch 语法中只支持整数类型以及这些整数类型的封装类进行判断,在 Java 7 中,支持了 string 字符串类型的判断,使用起来非常的简单,但是实用性是很高的。
编写一个简单的 switch 判断字符串的测试类。
public class SwitchWithString { public static void main(String[] args) { String gender = "男"; System.out.println(gender.hashCode()); switch (gender) { case "男": System.out.println("先生你好"); break; case "女": System.out.println("女士你好"); break; default: System.out.println("你好"); } } }switch 判断字符串使用起来很简单,结果也显而易见会先输出 gender 变量的 hashCode,然后输出匹配结果“先生你好”。
30007 先生你好在使用 switch string 时候,如果结合 Java 5 的枚举类,那么效果会更好,Java 7 之前使用枚举类要为每个值编数字代号,Java 7 之后可以直接定义字符串名称。
但是这个支持只是编译器层面的支持, JVM 依旧是不支持的。在对字符串进行 switch 时,编译器会把字符串转换成整数类型再进行判断。为了验证上面说的只是编译器层面的支持,我们反编译(可以使用 Jad 反编译工具,也可以在 Idea 中双击编译生成的 class )生成的 class 文件,看到编译器把 switch string 转换成了字符串 hashCode 判断,为了防止 hashCode 冲突,又使用了 equals 再次判断。
public class SwitchWithString { public SwitchWithString() { } public static void main(String[] args) { String gender = "男"; System.out.println(gender.hashCode()); byte var3 = -1; switch(gender.hashCode()) { case 22899: if (gender.equals("女")) { var3 = 1; } break; case 30007: if (gender.equals("男")) { var3 = 0; } } switch(var3) { case 0: System.out.println("先生你好"); break; case 1: System.out.println("女士你好"); break; default: System.out.println("你好"); } } }Java 不同于 C++,需要开发者自己管理每一块内存,大多时候 Java 虚拟机都可以很好的帮我们进行资源管理,但是也有时候需要手动释放一些资源,比如数据库连接、磁盘文件连接、网络连接等。换句话说,只要是资源数量有限的,都需要我们手动的进行释放。
在操作有限资源的时候,可能会出现各种异常,不管是读取阶段还是在最后关闭资源的过程中,都有可能出现问题,我们通常会使用下面的方式 try-catch-finally 保证资源的释放。
像下面这样。
/** * 释放资源 * * @author www.codingme.net */ public class TryCatachFinally { /** * 异常处理 * * @param args */ public static void main(String[] args) throws Exception { FileInputStream inputStream = null; try { inputStream = new FileInputStream("jdk-feature-7.iml"); } catch (FileNotFoundException e) { throw e; } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException e) { throw e; } } } } }看看这恶心的代码结构,为了捕获异常,我们写了一个 catch,为了能保证释放资源,我们又写了 finally 进行资源释放,在资源释放时为了捕捉 close 时抛出的异常,我们又写了一个 try-catch。最后看着这复杂的代码,如果有人告诉你这段代码有 bug,那你一定不会相信。但是确实是这样,看起来严密的代码逻辑,当 try 中的代码逻辑和 close 方法同时产生异常的时候,try 中的异常信息会丢失。
可以看这里例子。
package net.codingme.feature.jdk7; import java.io.IOException; /** * 释放资源 * * @author www.codingme.net */ public class TryCatachFinallyThrow { /** * 异常处理 * * @param args */ public static void main(String[] args) throws Exception { read(); } public static void read() throws Exception { FileRead fileRead = null; try { fileRead = new FileRead(); fileRead.read(); } catch (Exception e) { throw e; } finally { if (fileRead != null) { try { fileRead.close(); } catch (Exception e) { throw e; } } } } } class FileRead { public void read() throws Exception { throw new IOException("读取异常"); } public void close() throws Exception { System.out.println("资源关闭"); throw new IOException("关闭异常"); } }很明显代码里 read 和 close 方法都会产生异常,但是运行程序发现只能收到 close 的异常信息。
资源关闭 Exception in thread "main" java.io.IOException: 关闭异常 at net.codingme.feature.jdk7.FileRead.close(TryCatachFinallyThrow.java:51) at net.codingme.feature.jdk7.TryCatachFinallyThrow.read(TryCatachFinallyThrow.java:33) at net.codingme.feature.jdk7.TryCatachFinallyThrow.main(TryCatachFinallyThrow.java:20)异常信息丢失了,可怕的是你以为只是 close 时发生了异常而已。
上面的问题在 Java 7 中其实已经提供了新的解决方式,Java 7 中对 try 进行了增强,可以保证资源总能被正确释放 。使用增强 try 的前提是 try 中的类实现了 AutoCloseable 接口,在 Java 7 中大量的需要释放资源的操作其实都已经实现了此接口了。
实现了 AutoCloseable 的类,在增强 try中使用时,不用担心资源的关闭,在使用完毕会自动的调用 close方法,并且异常不会丢失。
让我们编写的模拟资源操作的类实现 AutoCloseable 接口,然后时候增强 try 看看效果。
package net.codingme.feature.jdk7; /** * 自动关闭 * * @author www.codingme.net */ public class AutoCloseResource { public static void main(String[] args) throws Exception { try (Mysql mysql = new Mysql(); OracleDatabase oracleDatabase = new OracleDatabase()) { mysql.conn(); oracleDatabase.conn(); } } } class Mysql implements AutoCloseable { @Override public void close() throws Exception { System.out.println("mysql 已关闭"); } public void conn() { System.out.println("mysql 已连接"); } } class OracleDatabase implements AutoCloseable { @Override public void close() throws Exception { System.out.println("OracleDatabase 已关闭"); } public void conn() { System.out.println("OracleDatabase 已连接"); } }测试类 Mysql 和 OracleDatabase 都是实现了 AutoCloseable,运行查看结果。
mysql 已连接 OracleDatabase 已连接 OracleDatabase 已关闭 mysql 已关闭确认在发生异常时候异常信息不会丢失,写一个有异常的模拟测试类进行测试。
package net.codingme.feature.jdk7; import java.io.IOException; /** * 释放资源 * * @author www.codingme.net */ public class AutoCloseThrow { public static void main(String[] args) throws Exception { try (FileReadAutoClose fileRead = new FileReadAutoClose()) { fileRead.read(); } } } class FileReadAutoClose implements AutoCloseable { public void read() throws Exception { System.out.println("资源读取"); throw new IOException("读取异常"); } @Override public void close() throws Exception { System.out.println("资源关闭"); throw new IOException("关闭异常"); } }运行查看异常信息。
资源读取 资源关闭 Exception in thread "main" java.io.IOException: 读取异常 at net.codingme.feature.jdk7.FileReadAutoClose.read(AutoCloseThrow.java:23) at net.codingme.feature.jdk7.AutoCloseThrow.main(AutoCloseThrow.java:14) Suppressed: java.io.IOException: 关闭异常 at net.codingme.feature.jdk7.FileReadAutoClose.close(AutoCloseThrow.java:29) at net.codingme.feature.jdk7.AutoCloseThrow.main(AutoCloseThrow.java:15)自动关闭,异常清晰,关闭异常存在于 Suppressed ,称为抑制异常,后续文章会详细介绍。
在 Java 7 之前,一个 catch 只能捕获一个异常信息,当异常种类非常多的时候就很麻烦,但是在 Java 7 中,一个 catch 可以捕获多个异常信息,每个异常捕获之间使用 | 分割,
package net.codingme.feature.jdk7; import java.io.IOException; /** * 多异常捕获 */ public class TryCatchMany { public static void main(String[] args) { try (TxtRead txtRead = new TxtRead()) { txtRead.reader(); } catch (IOException | NoSuchFieldException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } class TxtRead implements AutoCloseable { @Override public void close() throws Exception { System.out.println("资源释放"); } public void reader() throws IOException, NoSuchFieldException { System.out.println("数据读取"); } }需要注意的是,一个 catch 捕获多个异常时,不能出现重复的异常类型,也不能出现一个异常类型是另一个类的子类的情况。
Java 7 开始,可以直接指定不同的进制数字。
二进制指定数字值,只需要使用 0b 或者 OB 开头。八进制指定数字值,使用 0 开头。十六进制指定数字值,使用 0x 开头。/** * 二进制 * * @author www.codingme.net */ public class Binary { public static void main(String[] args) { // 二进制 System.out.println("------2进制-----"); int a = 0b001; int b = 0b010; System.out.println(a); System.out.println(b); // 八进制 System.out.println("------8进制-----"); int a1 = 010; int b1 = 020; System.out.println(a1); System.out.println(b1); // 十六进制 System.out.println("------16进制-----"); int a2 = 0x10; int b2 = 0x20; System.out.println(a2); System.out.println(b2); } }输出结果。
------2进制----- 1 2 ------8进制----- 8 16 ------16进制----- 16 32Java 7 开始支持在数字定义时候使用下划线分割,增加了数字的可读性。
/** * 数字下环线 * * @author www.codingme.net */ public class NumberLine { public static void main(String[] args) { int a = 1_000; int b = 1_0__0_0_0_____00; System.out.println(a); System.out.println(b); } }得到结果。
1000 1000000虽然 Java 7 早在 2011 年就已经发布了,但是据我发现,使用到 Java 7 开始的新特性新语法的并不多,所以我的 JDK 新特性系列文章计划从 Java 7 开始,一直介绍到目前已经发布的 Java 13,以后 Java 新版本更新的同时,这个新特性系列文章也会持续更新。
冲呀饼干人王国游戏下载v2.1.1 安卓版
经营养成 1.79G
下载尘白禁区手游官方版下载v2.4.0.98 安卓版
射击枪战 737.6M
下载合金弹头觉醒手游正版下载v1.15.0 官方安卓版
射击枪战 1.80G
下载qq飞车手游腾讯游戏下载v1.47.0.60405 安卓最新版
赛车竞速 1.99G
下载qq飞车手机版官方正版下载v1.47.0.60405 安卓版
赛车竞速 1.99G
下载腾讯游戏全民冠军足球最新版下载v1.0.3250 安卓版
体育运动 1.69G
下载剑侠世界3腾讯版下载v1.6.23488 安卓版
角色扮演 1.98G
下载世界启元手游下载v1.68.9807 安卓版
策略塔防 1.85G
下载海岛奇兵百度版最新版下载v54.2.1 安卓版
下载
传奇世界盛大正版手游下载v7.11.3.6 安卓版
下载
qq华夏手游官方最新版下载v5.9.0 安卓版
下载
网易永劫无间手游测试服下载v1.0.291536 安卓试玩版
下载
三国志幻想大陆官方正版下载v5.4.1 安卓最新版
下载
谁是卧底online苹果版下载v5.17.41 iphone版
下载
宝宝学汉字苹果app下载v9.80.2032 iphone版
下载
宝宝巴士电视版下载v8.7.30 安卓最新版
下载