• Java12新特性


    switch表达式(预览)

    传统switch的缺点

    1. 匹配是自上而下的,如果忘记写break, 后面的case语句不论匹配与否都会执行;
    2. 所有的case语句共用一个块范围,在不同的case语句定义的变量名不能重复;
    3. 不能在一个case里写多个执行结果一致的条件;
    4. 整个switch不能作为表达式返回值;

    预览语言

    switch 表达式是作为预览语言功能的第一个语言改动被引入新版 Java 中来的,预览语言功能的想法是在 2018 年 初被引入 Java 中的,本质上讲,这是一种引入新特性的测试版的方法。通过这种方式,能够根据用户反馈进行升级、更改,在极端情况下,如果没有被很好的接纳,则可以完全删除该功能。预览功能的关键在于它们没有被包含在 Java SE 规范中

    语法详解

    扩展的 switch 语句,不仅可以作为语句(statement),还可以作为表达式(expression),并且两种写法都可以使用传统的 switch 语法,或者使用简化的“case L ->”模式匹配语法作用于不同范围并控制执行流。这些更改将简化日常编码工作,并为 switch 中的模式匹配(JEP 305)做好准备

    1. 使用 Java 12 中 switch 表达式的写法,省去了 break 语句,避免了因少写 break 而出错。
    2. 同时将多个 case 合并到一行,显得简洁、清晰也更加优雅的表达逻辑分支,其具体写法就是将之前的 case 语 句表成了:case L ->,即如果条件匹配 case L,则执行标签右侧的代码 ,同时标签右侧的代码段只能是表达式、代码块或 throw 语句。
    3. 为了保持兼容性,case 条件语句中依然可以使用字符 : ,这时 fall-through 规则依然有效的,即不能省略原有 的 break 语句,但是同一个 Switch 结构里不能混用 -> 和 : ,否则会有编译错误。并且简化后的 switch 代码块中定义的局部变量,其作用域就限制在代码块中,而不是蔓延到整个 Switch 结构,也不用根据不同的判断条件来给变量赋值

    使用详解

    /**
     * 之前的写法,switch 语句如果漏写了一个 break,那么逻辑往往就跑偏了,这种方式既繁琐,又容易出错
     */
    public class SwitchTest {
        public static void main(String[] args) {
                int numberOfLetters;
                Fruit fruit = Fruit.APPLE; 
                switch (fruit) {
                      case PEAR:
                            numberOfLetters = 4;
                            break;
                      case APPLE:
                      case GRAPE:
                      case MANGO:
                          numberOfLetters = 5;
                          break;
                      case ORANGE:
                      case PAPAYA:
                          numberOfLetters = 6;
                          break;
                      default:
                            throw new IllegalStateException("No Such Fruit:" + fruit); 
                }
    
                System.out.println(numberOfLetters);
    } }
    
    enum Fruit {
        PEAR, APPLE, GRAPE, MANGO, ORANGE, PAPAYA;
    }
    
    /**
     * Java12中的switch 表达式
     */
    public class SwitchTest1 {
          public static void main(String[] args) {
                Fruit fruit = Fruit.GRAPE; 
                // Pattern Matching 机制能够自然地保证只有单一路径会被执行
                switch(fruit){
                      case PEAR -> System.out.println(4);
                      case APPLE,MANGO,GRAPE -> System.out.println(5);
                      case ORANGE,PAPAYA -> System.out.println(6);
                      default -> throw new IllegalStateException("No Such Fruit:" + fruit);
                }; 
                
                // 更进一步,下面的表达式,为我们提供了优雅地表达特定场合计算逻辑的方式
                int numberOfLetters = switch(fruit){
                      case PEAR -> 4;
                      case APPLE,MANGO,GRAPE -> 5;
                      case ORANGE,PAPAYA -> 6;
                      default -> throw new IllegalStateException("No Such Fruit:" + fruit);
                };
                System.out.println(numberOfLetters);
          }
    }
    

    Shenandoah GC:低停顿时间的GC(预览)

    Shenandoah 垃圾回收器是 Red Hat 在 2014 年宣布进行的一项垃圾收集器研究项目 Pauseless GC 的实现,旨在针对JVM 上的内存收回实现低停顿的需求。该设计将与应用程序线程并发,通过交换 CPU 并发周期和空间以改善停顿时间,使得垃圾回收器执行线程能够在 Java 线程运行时进行堆压缩,并且标记和整理能够同时进行,因此避免了在 大多数 JVM 垃圾收集器中所遇到的问题。
    据 Red Hat 研发 Shenandoah 团队对外宣称,Shenandoah 垃圾回收器的暂停时间与堆大小无关,这意味着无论将 堆设置为 200 MB 还是 200 GB,都将拥有一致的系统暂停时间,不过实际使用性能将取决于实际工作堆的大小和工 作负载。
    与其他 Pauseless GC 类似,Shenandoah GC 主要目标是 99.9% 的暂停小于 10ms,暂停与堆大小无关等。 这是一个实验性功能,不包含在默认(Oracle)的OpenJDK版本中。

    //推荐调试 Shenandoah 的 JVM 参数
    -XX:+AlwaysPreTouch:使用所有可用的内存分页,减少系统运行停顿,为避免运行时性能损失。
    -Xmx == -Xmsv:设置初始堆大小与最大值一致,可以减轻伸缩堆大小带来的压力,与 AlwaysPreTouch 参数配合使用,在启动时提交所有内存,避免在最终使用中出现系统停顿。
    -XX:+ UseTransparentHugePages:能够大大提高大堆的性能,同时建议在 Linux 上使用时将 /sys/kernel/mm/transparent_hugepage/enabled 和 /sys/kernel/mm/transparent_hugepage/defragv设置为:madvise,同时与 AlwaysPreTouch 一起使 用时,init 和 shutdownv 速度会更快,因为它将使用更大的页面进行预处理。
    -XX:+UseNUMA:虽然 Shenandoah 尚未明确支持 NUMA(Non-Uniform Memory Access),但最好启用此功 能以在多插槽主机上启用 NUMA 交错。与 AlwaysPreTouch 相结合,它提供了比默认配置更好的性能。
    -XX:+DisableExplicitGC:忽略代码中的 System.gc() 调用。当用户在代码中调用 System.gc() 时会强制 Shenandoah 执行 STW Full GC ,应禁用它以防止执行此操作,
    另外还可以使用 - XX:+ExplicitGCInvokesConcurrent,在 调用 System.gc() 时执行 CMS GC 而不是 Full GC,建议在有 System.gc() 调用的情况下使用。
    
    不过目前 Shenandoah 垃圾回收器还被标记为实验项目,如果要使用Shenandoah GC需要编译时--with-jvm- features选项带有shenandoahgc,然后启动时使用参数
    -XX:+UnlockExperimentalVMOptions -XX:+UseShenandoahGC
    

    JVM 常量 API

    Java 12 中引入 JVM 常量 API,用来更容易地对关键类文件 (key class-file) 和运行时构件(artefact)的名义描述 (nominal description) 进行建模,特别是对那些从常量池加载的常量,这是一项非常技术性的变化,能够以更简单、标准的方式处理可加载常量。
    具体来说就是java.base模块新增了java.lang.constant包(而非 java.lang.invoke.constant)。包中定义了一系列基于值的符号引用(JVMS 5.1)类型,它们能够描述每种可加载常量。

    官方文档:Java SE > Java SE Specifications > Java Virtual Machine Specification下的第5章: Chapter 5. Loading, Linking, and Initializing
    https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-5.html

    引入了ConstantDesc接口( )以及Constable接口;
    ConstantDesc接口定义了resolveConstantDesc方法,Constable接口定义了describeConstable方法;
    String、Integer、Long、Float、Double均实现了这两个接口,EnumDesc实现了 ConstantDesc接口

    符号引用以纯 nominal 形式描述可加载常量,与类加载或可访问性上下文区分开。有些类可以作为自己的符号引用 (例如 String)。而对于可链接常量,另外定义了一系列符号引用类型,具体包括: ClassDesc (Class 的可加载常量 标称描述符) ,MethodTypeDesc(方法类型常量标称描述符) ,MethodHandleDesc (方法句柄常量标称描述符) 和 DynamicConstantDesc (动态常量标称描述符) ,它们包含描述这些常量的 nominal 信息。此 API 对于操作类和方法的工具很有帮助

  • 相关阅读:
    B1001 害死人不偿命的(3n+1)猜想 (15 分)
    A1050 String Subtraction (20 分)
    A1041 Be Unique (20 分)
    B1047 编程团体赛 (20 分)
    B1043 输出PATest (20 分)
    B1042 字符统计 (20 分)
    B1038 统计同成绩学生 (20 分)
    VB计算符号
    vs2008写代码的时候不能输入中文,sogou和google输入法都没有用
    如何彻底关闭Windows7自动更新
  • 原文地址:https://www.cnblogs.com/ding-dang/p/13569866.html
Copyright © 2020-2023  润新知