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 对于操作类和方法的工具很有帮助

Java12新特性的更多相关文章

  1. Java12新特性 -- 默认生成类数据共享(CDS)归档文件

    默认生成类数据共享(CDS)归档文件 同一个物理机/虚拟机上启动多个JVM时,如果每个虚拟机都单独装载自己需要的所有类,启动成本和内 存占用是比较高的.所以Java团队引入了类数据共享机制 (Clas ...

  2. Java12新特性 -- switch表达式

    传统switch表达式的弊端: 匹配是自上而下的,如果忘记写break, 后面的case语句不论匹配与否都会执行: 所有的case语句共用一个块范围,在不同的case语句定义的变量名不能重复: 不能在 ...

  3. Java12新特性 -- 只保留一个 AArch64 实现

    现状 当前 Java 11 及之前版本JDK中存在两个64位ARM端口.这些文件的主要来源位于src/hotspot/cpu/arm 和 open/src/hotspot/cpu/aarch64 目录 ...

  4. Java12新特性 -- 增强G1,自动返回未用堆内存给操作系统

    Java 12 中增强了 G1 垃圾收集器关于混合收集集合的处理策略,这节主要介绍在 Java 12 中同时也对 G1垃圾回收器进行了改进,使其能够在空闲时自动将 Java 堆内存返还给操作系统,这也 ...

  5. Java12新特性 -- 可中断的 G1 Mixed GC

    G1是一个垃圾收集器,设计用于具有大量内存的多处理器机器.由于它提高了性能效率,G1垃圾收集器最终将取代CMS垃圾收集器. 该垃圾收集器设计的主要目标之一是满足用户设置的预期的 JVM 停顿时间. G ...

  6. Java12新特性 -- 其他新增,移除,废弃项

    支持unicode 11 JDK 12版本包括对Unicode 11.0.0的支持.在发布支持Unicode 10.0.0的JDK 11之后,Unicode 11.0.0引 入了以下JDK 12中包含 ...

  7. Java12新特性 -- JVM 常量 API

    Java 12 中引入 JVM 常量 API,用来更容易地对关键类文件 (key class-file) 和运行时构件(artefact)的名义描述 (nominal description) 进行建 ...

  8. Java12新特性 -- 微基准测试套件

    JMH,即Java Microbenchmark Harness,是专门用于代码微基准测试的工具套件.何谓Micro Benchmark呢?简单的来说就是基于方法层面的基准测试,精度可以达到微秒级.当 ...

  9. Java12新特性 -- Shenandoah GC

    Shenandoah 垃圾回收器是 Red Hat 在 2014 年宣布进行的一项垃圾收集器研究项目 Pauseless GC 的实现,旨在针对 JVM 上的内存收回实现低停顿的需求.该设计将与应用程 ...

随机推荐

  1. Linux权限之/etc/passwd文件

    在Linux /etc/passwd文件中每个用户都有一个对应的记录行,它记录了这个用户的一些基本属性.系统管理员经常会接触到这个文件的修改以完成对用户的管理工作.这个文件对所有用户都是可读的.但是L ...

  2. 仿京东BOE官网 jQuery代码

    $(function() { $("#chanping").mouseenter(function() { $("#column").slideDown(500 ...

  3. springboot的常用注解

    1. @SpringBootApplication2. @Repository3. @Service4. @RestController5. @Controller6. @Component7. @R ...

  4. CODING DevOps 代码质量实战系列第一课:代码规范与 Git Flow

    讲师介绍 杨周 CODING DevOps 架构师 CODING 布道师 连续创业者.DIY/Linux 玩家.知乎小 V,曾在创新工场.百度担任后端开发.十余年一线研发和带队经验,经历了 ToB.T ...

  5. go微服务系列(四) - http api中引入protobuf

    1. protobuf相关依赖安装 2. 改造之前的client 2.1 新建proto文件 2.2 运行protoc命令生成go文件 2.3 然后把原来的map修改成具体的类型就可以了 3. 处理j ...

  6. js动画和css3动画的区别

    JS动画(逐帧动画) 首先,在js动画是逐帧动画,是在时间帧上逐帧绘制帧内容,由于是一帧一帧的话,所以他的可操作性很高,几乎可以完成任何你想要的动画形式.但是由于逐帧动画的帧序列内容不一样,会增加制作 ...

  7. Linux安装Rabbitmq3.8.5

    安装环境: 操作系统为:centOS-7 erlang版本为22.3,软件包:otp_src_22.3.tar.gz rabbitMQ版本为3.8.5,软件包:rabbitmq-server-gene ...

  8. 在C++/CLI环境下,千万不要把普通全局函数当标准C/C++的函数指针传递给native的库使用

    先上一个简单代码: #include <cstdlib> #include <cstdio> // native apis extern "C" { typ ...

  9. Istio 的配置分析

    Istio 的配置分析 目录 Istio 的配置分析 Analyzer 的消息格式 ConflictingMeshGatewayVirtualServiceHosts 问题解决 举例 Conflict ...

  10. 会话技术之 Session

    会话技术之 Session 不多废话,先来一个 HelloWorld. Session 有 get 肯定要先有 set . @Override protected void service(HttpS ...