zoukankan      html  css  js  c++  java
  • jdk13-新特性预览

    一新特性

    350: Dynamic CDS Archives(动态CDS档案)
    351: ZGC: Uncommit Unused Memory(ZGC:取消提交未使用的内存)
    353: Reimplement the Legacy Socket API(重新实现旧版套接字API)
    354: Switch Expressions (Switch表达式)
    355: Text Blocks(文字块)

    二动态CDS归档(扩展应用程序类数据共享)

    2.1主要实现功能:

    允许在Java应用程序执行结束时动态归档类。归档的类将包括默认基层CDS归档中不存在的所有已加载应用程序类和库类。

    2.2支持存档配置

    方式一:基本静态存档(默认存档)+ 动态存档;
    方式二:仅基本静态存档;
    说明:动态存档是基于静态存档实现的,如果静态存档没有映射成功,动态存档无法实现。

    2.3前提要求

    1 需要运行一次或者多次生成class列表
    2使用class列表存档
    3将存档和应用一起运行

    2.4生成动态存档指令

    用户可以指定动态档案的文件名做为-XX:ArchiveClassesAtExit选项的入参。
    示例创建动态归档hello.jsa :

    % bin/java -XX:ArchiveClassesAtExit=hello.jsa -cp hello.jar Hello
    

    将归档文件和同一个应用运行:

    % bin/java -XX:SharedArchiveFile=hello.jsa -cp hello.jar Hello
    

    2.3归档依赖性

    动态创建的顶层归档取依赖于基础层存档(它包含指向基础层数据的指针),因此基础存档头和所有共享空间的CRC值都会记录在顶层中。

    在运行时,当映射动态归档时,会将所有记录的CRC值与当前映射的基本归档CRC值进行比较。如果任何CRC值都不匹配,则禁用动态归档,而不会影响当前映射的基本归档的使用。

    2.4动态档案的共享空间

    动态档案的共享空间的元数据和静态档案的元数据类似。分割成4个空间不需md空间。
    rw:读写
    ro:只读
    mc:
    在运行的时候会分别映射
    一台主机上运行可以运行同一套库的多个进程:
    2个进程: -cp:lib.jar:foo.jar FooApp
    4个进程: -cp:lib.jar:bar.jar BarApp
    然后创建2个归档一个用在foo进程上,一个用在bar进程上,就是共享6个进程,达到节省内存目的。

    三ZGC:取消提交未使用的内存

    3.1实现功能:

    将未使用的堆内存还给系统(即未提交的内存空间)

    3.2原理概述

    ZGC堆由一组称为ZPages的堆区域组成。每个ZPage与可变数量已提交的堆内存关联。当ZGC压缩堆时,ZPage被释放并插入到ZPageCache(页面缓存)中。页面缓存中的ZPage已准备好重新使用以满足新的堆分配,在这种情况下,它们将从缓存中删除。页面缓存对性能十分重要,提交和取消提交是非常昂贵的操作

    Zpage退出页面缓存的时机:
    Zpage在页面缓存停留5分钟(默认值)后退出缓存,可以使用 -XX:ShenandoahUncommitDelay= 参数覆盖默认值

    取消提交功能是默认启用(JVM选项:-XX:-ZUncommit),否则会引起堆内存低于最小大小堆(-Xms),最大最小堆方式启用的JVM会有禁用取消提交功能的提示。

    四重新实现旧版套接字API

    4.1简要说明:

    会用更简单的实现方式替换java.net.Socket和java.net.ServerSocketAPI ,新的实现正在Project Loom中进行探索。

    五 switch表达式

    5.1功能实现:

    主要是对switch表达式进行扩展,支持原有的case方式和新的case方式。新的case语句更加精炼简洁。
    使用yield语句返回值,放弃了break语句。

    5.2通常语法格式

    T result = switch (arg) {
        case L1 -> e1;
        case L2 -> e2;
        default -> e3;
    };
    

    5.3官方示例1

    官方提供旧版本丢失了break的switch语句:

    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            System.out.println(6);
            break;
        case TUESDAY:
            System.out.println(7);
            break;
        case THURSDAY:
        case SATURDAY:
            System.out.println(8);
            break;
        case WEDNESDAY:
            System.out.println(9);
            break;
    }
    

    java13中的语法格式(提倡"case L ->"语法格式,提倡常量中用逗号隔开):

    switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
        case TUESDAY                -> System.out.println(7);
        case THURSDAY, SATURDAY     -> System.out.println(8);
        case WEDNESDAY              -> System.out.println(9);
    }
    

    5.4官方示例2:

    老版本

    int numLetters;
    switch (day) {
        case MONDAY:
        case FRIDAY:
        case SUNDAY:
            numLetters = 6;
            break;
        case TUESDAY:
            numLetters = 7;
            break;
        case THURSDAY:
        case SATURDAY:
            numLetters = 8;
            break;
        case WEDNESDAY:
            numLetters = 9;
            break;
        default:
            throw new IllegalStateException("Wat: " + day);
    }
    

    jdk13新版本(官方提倡直接计算出值赋值给变量)

    int numLetters = switch (day) {
        case MONDAY, FRIDAY, SUNDAY -> 6;
        case TUESDAY                -> 7;
        case THURSDAY, SATURDAY     -> 8;
        case WEDNESDAY              -> 9;
    };
    

    官方示例3(yield表达):

    新版本:

    int j = switch (day) {
        case MONDAY  -> 0;
        case TUESDAY -> 1;
        default      -> {
            int k = day.toString().length();
            int result = f(k);
            yield result;
        }
    };
    

    新版本:

    int result = switch (s) {
        case "Foo": 
            yield 1;
        case "Bar":
            yield 2;
        default:
            System.out.println("Neither Foo nor Bar, hmmm...");
            yield 0;
    };
    
    

    5.4箭头标签语法特性

    ”case L -> “语法格式,如果标签匹配,则仅执行箭头右侧的表达式或语句;否则,将不执行任何操作(没有失败)

    static void howMany(int k) {
        switch (k) {
            case 1  -> System.out.println("one");
            case 2  -> System.out.println("two");
            default -> System.out.println("many");
        }
    }
    
    

    执行输出:

    howMany(1);//one
    howMany(2);//two
    howMany(3);//many
    
    

    5.5注意点

    switch表达式必须以一个值正常完成,或者必须通过引发异常来突然完成,这回出现一些不完美的结果
    首先,编译器会检查每个开关标签是否匹配,其次,控制语句,break,yield,return和continue,无法跳出switch表达式。
    示例:

    z: 
        for (int i = 0; i < MAX_VALUE; ++i) {
            int k = switch (e) { 
                case 0:  
                    yield 1;
                case 1:
                    yield 2;
                default: 
                    continue z; 
                    // ERROR! Illegal jump through a switch expression 
            };
        ...
        }
    
    

    六文字块

    6.1 实现功能

    将文本块添加至java语言,多行字符串不需要转义,提高代码的可读性。

    6.2HTML示例

    使用一维字符串:

    String html = "<html>
    " +
                  "    <body>
    " +
                  "        <p>Hello, world</p>
    " +
                  "    </body>
    " +
                  "</html>
    ";
    
    

    使用二维文本块

    String html = """
                  <html>
                      <body>
                          <p>Hello, world</p>
                      </body>
                  </html>
                  """;
    
    

    6.3SQL示例

    使用一维字符串:

    String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
    " +
                   "WHERE `CITY` = 'INDIANAPOLIS'
    " +
                   "ORDER BY `EMP_ID`, `LAST_NAME`;
    ";
    
    

    使用二维文本块:

    String query = """
                   SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
                   WHERE `CITY` = 'INDIANAPOLIS'
                   ORDER BY `EMP_ID`, `LAST_NAME`
                    """;
    
    

    6.4使用多语言例子

    一维字符串:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
    Object obj = engine.eval("function hello() {
    " +
                             "    print('"Hello, world"');
    " +
                             "}
    " +
                             "
    " +
                             "hello();
    ");
    
    

    二维文本块:

    ScriptEngine engine = new ScriptEngineManager().getEngineByName("js");
    Object obj = engine.eval("""
                             function hello() {
                                 print('"Hello, world"');
                             }
                             
                             hello();
                             """);
    
    

    6.5等效例子1

    """
    line 1
    line 2
    line 3
    """
    
    

    等效于

    "line 1
    line 2
    line 3
    "
    
    

    等效于

    "line 1
    " +
    "line 2
    " +
    "line 3
    "
    
    

    等效例子2(字符串的末尾不需要行终止符)

    """
    line 1
    line 2
    line 3"""
    
    

    等效于

    "line 1
    line 2
    line 3"
    
    

    等效于

    String empty = """
    """;
    
    

    七参考链接(官网)

    http://openjdk.java.net/projects/jdk/13/

    八寄语

    新版本的jdk固然加了新特性,但是我们的其他配套开发工具是否能跟上jdk半年一个版本的升级是一个问题。
    而且新版本的jdk刚刚出来肯定有许多要改进的地方,鉴于学习我们是可以使用新版,如果是实际生产环境我觉得还是旧版本的jdk8,jdk11较好。
    在这里插入图片描述

  • 相关阅读:
    java加载类的方法1.classloader 2.class.forName()
    servlet与线程与jdbc connection的关系
    static再次深入理解
    多线程读某个共享变量有时候也要给读方法加锁
    多线程读一个全局变量要不要加锁?还是说只是当修改全局变量的时候才要加锁?
    接口耗时打印并统计
    Java从设计模式[本场比赛状态转换武器]状态分析(State)模式
    Openstack中间DVR Part1 -- 东西走向的交通处理
    写酷“大神”的公开信
    从反思谈论阵列和指针的几个问题,腾讯的笔名
  • 原文地址:https://www.cnblogs.com/zszxz/p/12066834.html
Copyright © 2011-2022 走看看