4. 接口私有方法
在 Java 8
中增加了默认方法,在 Java 9
中又增加了私有方法,这时开始接口中不仅仅有了定义,还具有了行为。我想这是出于代码构造上的考虑,如果没有私有方法,那么当多个默认方法的行为一样时,就要写多个相同的代码。而有了私有方法,事情就变得不一样了。
就像下面的例子。
/** * @author 达西 - 公众号:未读代码 */ publicclass Jdk9Interface { public static void main(String[] args) { ChinaPeople chinaPeople = new ChinaPeople(); chinaPeople.sleep(); chinaPeople.eat(); chinaPeople.doXxx(); } } class ChinaPeople implements People { @Override public void sleep() { System.out.println("躺着睡"); } } interface People { void sleep(); default void eat() { drink(); } default void doXxx() { drink(); } private void drink() { System.out.println("喝水"); } }
例子中的接口 people
中的 eat()
和 doXxx()
默认行为一致,使用私有方法可以方便的抽取一个方法出来。
输出结果。
躺着睡 喝水 喝水
5. HTTP / 2 Client
Java 9
内置了新的 HTTP/2 客户端,请求更加方便。
随便访问一个不存在的网页。
HttpClient client = HttpClient.newHttpClient(); URI uri = URI.create("http://www.tianqiapi.com/api/xxx"); HttpRequest req = HttpRequest.newBuilder(uri).header("User-Agent", "Java").GET().build(); HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandler.asString()); String body = resp.body(); System.out.println(body);
输出得到的结果,这里是这个网站的报错信息。
There is no method xxxAction in ApiController
可能你运行的时候会报找不到 httpClient
模块之类的问题,这时候需要你在你项目代码目录添加 httpClient 模块
才能解决,添加方式看下面的图。
Java 9 导入导出模块
export
写自己的包路径,requires
写引入的模块名。
6. Java REPL - JShell
交互式的编程环境在其他语言如 Python 上早就有了,而 Java 上的交互式语言只到 Java 9
才出现。交互式的编程可以让开发者在输入代码的时候就获取到程序的运行结果,而不用像之前一样新建文件、创建类、导包、测试一系列流程。
JShell
中支持 tab
补全代码以及自动添加分号,下面通过一个例子演示 JShell
的使用。
- 进入 JShell. 查看帮助文档。
C:\Users>jshell | 欢迎使用 JShell -- 版本 9 | 要大致了解该版本, 请键入: /help intro jshell> /help | 键入 Java 语言表达式, 语句或声明。 | 或者键入以下命令之一: | /list [<名称或 id>|-all|-start] | 列出您键入的源 | /edit <名称或 id> | 编辑按名称或 id 引用的源条目 | /drop <名称或 id> | 删除按名称或 id 引用的源条目 | /save [-all|-history|-start] <文件> | 将片段源保存到文件。 | /open <file> | 打开文件作为源输入 | /vars [<名称或 id>|-all|-start] | 列出已声明变量及其值 | /methods [<名称或 id>|-all|-start] | 列出已声明方法及其签名 | /types [<名称或 id>|-all|-start] | 列出已声明的类型 | /imports | 列出导入的项 | /exit | 退出 jshell | /env [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>] ... | 查看或更改评估上下文 | /reset [-class-path <路径>] [-module-path <路径>] [-add-modules <模块>]... | 重启 jshell | /reload [-restore] [-quiet] [-class-path <路径>] [-module-path <路径>]... | 重置和重放相关历史记录 -- 当前历史记录或上一个历史记录 (-restore) | /history | 您键入的内容的历史记录 | /help [<command>|<subject>] | 获取 jshell 的相关信息 | /set editor|start|feedback|mode|prompt|truncation|format ... | 设置 jshell 配置信息 | /? [<command>|<subject>] | 获取 jshell 的相关信息 | /! | 重新运行上一个片段 | /<id> | 按 id 重新运行片段 | /-<n> | 重新运行前面的第 n 个片段 | | 有关详细信息, 请键入 '/help', 后跟 | 命令或主题的名称。 | 例如 '/help /list' 或 '/help intro'。主题: | | intro | jshell 工具的简介 | shortcuts | 片段和命令输入提示, 信息访问以及 | 自动代码生成的按键说明 | context | /env /reload 和 /reset 的评估上下文选项 jshell>
- 定义一个变量:a = 10,遍历从 0 到 a 的数字。
jshell> int a =10; a ==> 10 jshell> for(int i=0;i<a;i++){System.out.println(i);} 0 1 2 3 4 5 6 7 8 9
- 定义一个集合,赋值1,2,3,4,5。然后输出集合。
jshell> List list = List.of(1,2,3,4,5); list ==> [1, 2, 3, 4, 5] jshell> list list ==> [1, 2, 3, 4, 5]
- 查看输入过的代码。
jshell> /list 1 : int a =10; 2 : for(int i=0;i<a;i++){System.out.println(i);} 3 : List list = List.of(1,2,3,4,5); 4 : list
- 列出导入的包。
jshell> /imports | import java.io.* | import java.math.* | import java.net.* | import java.nio.file.* | import java.util.* | import java.util.concurrent.* | import java.util.function.* | import java.util.prefs.* | import java.util.regex.* | import java.util.stream.*
- 将代码保存到文件并退出。
jshell> /save d:/JShell.java jshell> /exit 再见
在 D 盘看到的保存的代码片段。
JShell 保存的代码
操作起来还是挺简单的,还记得上面介绍集合工厂 of
方法创建出来的 set
和 map
数据在每个 JVM
周期里是无序的嘛?也可以用 JShell
实验下。
Set.of 的随机遍历
7. 其他更新
Java 9
中增加或者优化的功能远不止这些,上面只是列举了常用的一些新特性,更多的新特性如:
- 不能使用下划线 _ 作为变量名,因为它是一个关键字。
- Javadoc 支持 HTML5 并且支持搜索功能。
- Nashorn 引擎升级,更好的支持 Javascript.
- String 存储结构变更从 char -> byte.
- .........
新特性很多,感兴趣的可以自己了解下。
再次预告,后续文章会结合案例图文并茂详细介绍 Java 9 开始的模块系统,感兴趣的可以关注我。此去山高水远,愿你我一路同行。
文章案例都已经上传到 Github:niumoo/jdk-feature
参考资料
- Java Platform, Standard Edition What’s New in Oracle JDK 9