1. Switch 表达式(预览特性)
Java 12 引入了 Switch 表达式,使得 switch 语句不仅可以用作语句(statement),还可以用作表达式(expression)。这意味着可以将 switch 的结果直接赋值给一个变量。
示例:
public class SwitchExpressionDemo {
public static void main(String[] args) {
int dayOfWeek = 3; // 假设 1 = 星期一,2 = 星期二,3 = 星期三,依此类推
String dayName = switch (dayOfWeek) {
case 1 -> "Monday";
case 2 -> "Tuesday";
case 3 -> "Wednesday";
case 4 -> "Thursday";
case 5 -> "Friday";
case 6 -> "Saturday";
case 7 -> "Sunday";
default -> throw new IllegalArgumentException("Invalid day: " + dayOfWeek);
};
System.out.println("Day: " + dayName);
}
}
详细解释:
- 在这个示例中,
switch
表达式用箭头 (->
) 语法定义了每个 case 的返回值。 - 这种方式不仅使代码更简洁,而且避免了使用
break
语句来防止 fall-through 的问题。 -
default
分支可以抛出异常,处理非法输入。
2. JVM 常量接口(JEP 334)
Java 12 允许开发者在接口中定义常量,这些常量可以直接在实现类中使用,避免了使用静态常量的繁琐。
示例:
public interface Constants {
String GREETING = "Hello, World!";
}
public class ConstantsDemo implements Constants {
public static void main(String[] args) {
System.out.println(GREETING); // 输出: Hello, World!
}
}
详细解释:
- 接口中的常量是隐式
public static final
,可以被实现类直接访问。 - 这种方式使得常量的定义更加集中,增强了代码的可维护性。
3. 堆外内存的改进
Java 12 引入了对堆外内存的支持,允许开发者更灵活地管理内存,尤其是在处理大数据和高性能计算时。
示例:
import jdk.incubator.foreign.*;
public class OffHeapMemoryDemo {
public static void main(String[] args) {
MemorySegment segment = MemorySegment.allocateNative(1024); // 分配 1024 字节的堆外内存
segment.set(ValueLayout.JAVA_INT, 0, 42); // 在堆外内存中设置一个整数值
int value = segment.get(ValueLayout.JAVA_INT, 0); // 从堆外内存中获取值
System.out.println("Value: " + value); // 输出: Value: 42
segment.close(); // 释放堆外内存
}
}
详细解释:
- 使用
MemorySegment
类可以分配和管理堆外内存。 - 这种方式适合需要高性能和大内存的场景,如处理大型数据集或高性能计算。
-
close()
方法用于释放堆外内存,避免内存泄漏。
4. 新垃圾收集器(Shenandoah,预览特性)
Java 12 引入了 Shenandoah 垃圾收集器,旨在提供低延迟的垃圾回收,适合对响应时间要求高的应用程序。
示例:
Shenandoah 是一种 JVM 选项,无法通过代码示例直接展示。要启用 Shenandoah,可以在启动应用程序时使用以下参数:
java -XX:+UseShenandoahGC -jar yourapp.jar
详细解释:
- Shenandoah 垃圾收集器通过并行和并发的方式进行内存回收,减少了停顿时间。
- 适合需要快速响应的应用程序,如金融服务、在线游戏等。
5. 增强的 NullPointerException(JEP 358)
Java 12 改进了 NullPointerException 的错误信息,使得调试更为方便。新的异常信息会显示出导致空指针异常的具体位置。
示例:
public class NPEDemo {
public static void main(String[] args) {
String str = null;
// 触发 NullPointerException
try {
System.out.println(str.length());
} catch (NullPointerException e) {
System.out.println("Caught NullPointerException: " + e.getMessage());
}
}
}
详细解释:
- 在 Java 12 中,如果
str
为null
,则 NullPointerException 的信息将更为详细,指明是哪个对象为null
。 - 这种改进使得开发者在调试时更容易定位问题。