写点什么

Java9 新特性 - 上篇

用户头像
hepingfly
关注
发布于: 2020 年 11 月 02 日
Java9新特性-上篇

1、目录结构变化

1)、Java9 之前的目录结构


2)、Java9 之后的目录结构


说明:


在 JDK9 中

  • 删除了 JRE 的子目录

  • bin 目录包含所有的命令

  • conf 目录包含用户可编辑的配置文件

  • include 目录包含编译本地代码时使用的 C/C++头文件

  • jmods 目录包含 JMOD 格式的平台模块

  • legal 目录包含法律声明

  • lib 目录包含一些动态链接库


2、模块化系统

1)、模块化系统产生的背景


Java 已经发展超过 20 年(95 年发布),Java 和相关生态在不断丰富的同时也暴露出了一些问题。

  • Java 运行环境的膨胀和臃肿。每次 JVM 启动的时候,至少会有 30~60M 的内存加载。主要原因是 JVM 需要加载 rt.jar ,不管其中的类是否被 classloader 加载,第一步整个 jar 都会被 JVM 加载到内存中去,而模块化可以根据模块的需要加载程序运行需要的 class 。

  • 很难真正的对代码进行封装,而系统并没有对不同部分(也就是 jar 文件)之间的依赖关系有个明确的概念。每一个公共的类都可以被类路径之下任何其他的公共类访问到,这样就会导致无意中使用了并不想被公开访问的 API 。

  • 本质上说,模块(module)的概念,其实就是 package 外再包裹一层,也就是说,用模块来管理各个 package ,通过声明某个 package 暴露,不声明默认就是隐藏。因此模块化是的代码组织上更安全,因为它可以指定哪些部分暴露,哪些部分隐藏。


2)、代码说明



① 创建一个 java9demo 的工程,然后在这个工程下面创建 2 个 module。一个 java9A ,一个 java9B

② 在 java9A 中创建一个实体类 Person,然后想在 java9B 中引用它,正常情况下是引用不到的,因为是存在两个模块中。

③ 我们在 java9A 模块的 src 目录下新建 module-info.java 文件

module java9A {    // 这里 exports 后面跟具体的包名    exports com.hepingfly.bean;}
复制代码


④ 我们在 java9B 模块的 src 目录下新建 module-info.java 文件

module java9demo {    // requires 后面跟具体要引入的 module 的名字    requires java9A;}
复制代码


⑤ 这样在 java9B 模块中就能引用 java9A 模块暴露出来的实体类了。

public class ModuleTest {    // 我在 java9B 模块中想引用 java9A 模块中的 Person 类    public static void main(String[] args) {        Person person = new Person();        person.setName("hepingfly");        System.out.println(person.getName());   // 打印 hepingfly    }}
复制代码


3、jshell 命令的使用


1)、产生的背景


像 Python 和 Scala 之类的语言早就有交互式编程环境 REPL(read-evaluate-print-loop)了,以交互的方式对语句和表达式进行求值。开发者只需要输入一些代码,就可以在编译前获得对程序的反馈。而之前的 Java 版本要想执行代码,必须创建文件、声明类、提供测试方法方可实现。


2)、jshell 简单介绍


在 Java9 中终于拥有了 REPL 工具:jShell 。利用 jshell 可以在没有创建类的情况下直接声明变量,计算表达式,执行语句。即开发时可以在命令行里直接运行 Java 代码,无需创建 Java 文件。


3)、基本使用


① JDK9 以上的版本如果你配置好了环境变量直接在命令行输入 jshell 即可进入交互界面(原因是 JDKbin 目录下有 jshell 这个工具)


② 输入命令获得帮助信息


③ 定义变量,计算变量值


④ 定义方法,调用方法


⑤ 导入指定的包


⑥ 列出当前 session 内所有有效的代码片段


⑦ 查看当前 session 下所有创建过的变量


⑧ 查看当前 session 下所有创建过的方法


⑨ 从外部文件加载源代码

源代码:

// hello.java 文件中的内容public void hello() { System.out.println("helllo hepingfly");}hello();
复制代码



⑩ 退出 jshell


注:


  • jshell 可以使用 tab 键进行自动补全

  • jshell 可以从文件中加载语句或者将语句保存到文件中

  • 在 jshell 中定义相同方法名和参数列表的方法,即为对现有方法的覆盖。

  • 在 jshell 中你会发现不会出现编译时异常,因为 jshell 帮你隐藏了。


4、接口中定义私有方法


在 Java9 中,接口更加灵活和强大,方法的访问权限修饰符可以声明为 private 的了,此时方法将不会成为你对外暴露的 API 的一部分。

① JDK7:


JDK7:

1)、只能声明全局常量(public static final)

2)、抽象方法(public abstract)


② JDK8:


JDK8:

1)、可以声明静态方法

2)、可以声明默认方法静态方法和默认方法在接口中都是有方法体的, 也就意味着我们可以通过接口名去调用这个静态方法,或者通过这个接口的实现类对象来调用默认方法


③ JDK9:


JDK9:

1)、支持声明私有方法


/** * java9 接口 * @author hepingfly * @date 2020/10/24 2:31 下午 */public interface Java9Interface {
/** * JDK7: * 1)、只能声明全局常量(public static final) * 2)、抽象方法(public abstract) * @author hepingfloy * @date 2020/10/24 2:33 下午 */ void hello();
/** * JDK8: * 1)、可以声明静态方法 * 2)、可以声明默认方法 * 静态方法和默认方法在接口中都是有方法体的, 也就意味着我们可以通过 * 接口名去调用这个静态方法,或者通过这个接口的实现类对象来调用默认方法 * @author hepingfly * @date 2020/10/24 2:36 下午 */ static void hello2() { System.out.println("hepingfly"); }
default void hello3() { System.out.println("hepingfly"); }
/** * JDK9: * 1)、支持声明私有方法 * @author hepingfly * @date 2020/10/24 2:53 下午 */ private void hello4() { System.out.println("hepingfly"); }}
复制代码



5、钻石操作符使用升级


可以与匿名实现类共同使用钻石操作符。

public class DiamondOperator {    public static void main(String[] args) {        // java8 中这么写会报错,java9 可以        Set<String> set = new HashSet<>(){};    }}
复制代码


发布于: 2020 年 11 月 02 日阅读数: 38
用户头像

hepingfly

关注

视频号:hepingfly 分享干货,欢迎关注~ 2018.06.23 加入

B站程序员。目标是做一个有才华,身上有光的男人。

评论

发布
暂无评论
Java9新特性-上篇