自Java 8以后,随着新版本的发布,Java继续引入了多项新特性来进一步增强语言的表达力和功能。以下是一些Java 8之后版本中的进阶语法特性,包括示例代码:
局部变量类型推断 (Java 10):
Java 10引入了var
关键字,允许在局部变量声明时省略显式类型,由编译器推断变量的类型。这使得代码更简洁,特别是对于泛型代码。
// 使用var进行局部变量类型推断
var list = new ArrayList<String>(); // 推断为ArrayList<String>
var stream = list.stream(); // 推断为Stream<String>
增强的switch表达式 (Java 12, 13增强):
Java 12引入了对switch表达式的增强,允许它返回一个值,并且可以有更简洁的语法。Java 13进一步增强了这个特性,提供了更多的模式匹配能力。
// 增强的switch表达式,需要--enable-preview在编译和运行时开启
String day = "MON";
var typeOfDay = switch(day) {
case "MON", "TUE", "WED", "THU", "FRI" -> "Weekday";
case "SAT", "SUN" -> "Weekend";
default -> throw new IllegalArgumentException("Invalid day: " + day);
};
System.out.println(typeOfDay); // 输出:Weekday
文本块 (Java 13):
Java 13添加了文本块(或多行字符串),它允许嵌入由三个双引号定界的多行字符串文字,简化了包含大量文本的字符串的处理。
// 文本块示例,需要--enable-preview在编译和运行时开启
String json = """
{
"name": "John",
"age": 30
}
""";
System.out.println(json);
Records (Java 14):
Java 14引入了Records作为轻量级的数据载体,它简化了创建包含数据的不可变类的过程。每个record都会自动提供构造器、访问器、equals、hashCode和toString方法。
// Record示例,需要--enable-preview在编译和运行时开启
record Point(int x, int y) { }
Point p = new Point(1, 2);
System.out.println(p.x()); // 输出:1
System.out.println(p.y()); // 输出:2
Pattern Matching for instanceof (Java 16):
Java 16增强了instanceof
操作符,使其能够自动进行类型转换,简化了代码中的类型检查和转换。
// Pattern Matching for instanceof 示例
Object obj = "Hello, World!";
if (obj instanceof String s) { // 自动转换成String类型
System.out.println(s.toUpperCase()); // 输出:HELLO, WORLD!
}
Sealed Classes (Java 17):
Java 17引入了密封类和接口,它们限制了其他类或接口可以扩展或实现的可能性。这为类层次结构引入了受控的多态性。
// Sealed类示例,需要在编译和运行时开启预览特性
public sealed class Shape permits Circle, Square {
// 类定义
}
final class Circle extends Shape {
// 类定义
}
non-sealed class Square extends Shape {
// 类定义
}
Stream API的改进 (Java 9):
Java 9对Stream API进行了增强,添加了新的方法,比如takeWhile
, dropWhile
和ofNullable
。
// 使用takeWhile来获取满足条件的前缀子序列
var numbers = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
var result = numbers.takeWhile(n -> n < 5).collect(Collectors.toList());
System.out.println(result); // 输出 [1, 2, 3, 4]
// 使用dropWhile来丢弃满足条件的前缀子序列
var numbers2 = Stream.of(1, 2, 3, 4, 5, 6, 7, 8, 9);
var result2 = numbers2.dropWhile(n -> n < 5).collect(Collectors.toList());
System.out.println(result2); // 输出 [5, 6, 7, 8, 9]
Optional类的改进 (Java 9):
Java 9对Optional
类进行了改进,添加了ifPresentOrElse
和stream
方法。
// 使用ifPresentOrElse对Optional值进行条件操作
Optional<String> optionalValue = Optional.of("Hello");
optionalValue.ifPresentOrElse(
System.out::println, // 如果值存在,执行这个Consumer
() -> System.out.println("Value not present") // 否则执行这个Runnable
);
// 使用stream将Optional转换为Stream
Stream<String> stream = optionalValue.stream();
HttpClient API (Java 11):
Java 11引入了新的HTTP客户端API,它支持HTTP/2协议和WebSocket,并且比旧的HttpURLConnection
更易用。
// 使用新的HttpClient发送GET请求
HttpClient httpClient = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.body());
垃圾回收器的改进:
Java不断改进其垃圾回收器,包括G1、ZGC和Shenandoah GC,以提供更低的延迟和更好的性能。
// 启用不同的垃圾回收器,通常是通过JVM启动参数进行配置
// 例如,使用G1垃圾回收器
// java -XX:+UseG1GC MyApp
// 或者,使用ZGC垃圾回收器(在支持的平台上)
// java -XX:+UseZGC MyApp
模块系统 (Java 9):
Java 9引入了一个全新的模块系统(Jigsaw项目),它允许将应用程序划分为模块,以提供更好的封装性和依赖管理。
// module-info.java文件定义了模块的名称和依赖
module com.myapp {
requires java.base;
exports com.myapp.service;
}
接口中的私有方法 (Java 9):
Java 9允许在接口中定义私有方法和私有静态方法,这有助于接口中的方法共享代码。
public interface MyInterface {
private static String getDefaultGreeting() {
return "Hello, World!";
}
default void greet() {
String greeting = getDefaultGreeting();
System.out.println(greeting);
}
}
嵌套的基于性能的优化 (Java 11):
Java 11对嵌套类进行了一些基于性能的优化,包括对内部类和嵌套类的访问控制的改进。
public class OuterClass {
private String outerField = "Outer field";
private static String staticOuterField = "Static outer field";
class InnerClass {
public void showFields() {
System.out.println(outerField);
System.out.println(staticOuterField);
}
}
}
String类的改进 (Java 11):
Java 11对String
类进行了增强,添加了一些新的实用方法,例如strip
, stripLeading
, stripTrailing
, isBlank
, lines
, repeat
.
// String类新方法示例
String multilineString = "This is\n \n a multiline\n string.";
multilineString.lines().forEach(System.out::println); // 按行打印字符串
String str = " hello ";
System.out.println(str.strip()); // 去除首尾空白字符
System.out.println(str.isBlank()); // 检查字符串是否为空白
System.out.println("repeat".repeat(3)); // 重复字符串内容
Files.readString 和 Files.writeString (Java 11):
Java 11在Files
类中添加了readString
和writeString
方法,简化了文件内容的读写操作。
// 使用Files.readString和Files.writeString
Path filePath = Paths.get("example.txt");
String content = "Hello, World!";
Files.writeString(filePath, content); // 写入字符串到文件
String result = Files.readString(filePath); // 从文件读取字符串
System.out.println(result);
Compact Number Formatting (Java 12):
Java 12引入了紧凑型数字格式化,可以更容易地以短形式显示数字,例如“1千”代替“1000”。
// Compact Number Formatting示例
NumberFormat compactNumberFormat = NumberFormat.getCompactNumberInstance(Locale.US, NumberFormat.Style.SHORT);
String formatted = compactNumberFormat.format(1000);
System.out.println(formatted); // 输出: 1K
Switch表达式 (Java 14):
Java 14正式引入了switch表达式作为标准特性,用于返回值,并允许多个case标签共享相同的结果。
// Switch表达式示例
int month = 3;
String quarter = switch (month) {
case 1, 2, 3 -> "First Quarter";
case 4, 5, 6 -> "Second Quarter";
case 7, 8, 9 -> "Third Quarter";
case 10, 11, 12 -> "Fourth Quarter";
default -> throw new IllegalArgumentException("Invalid month: " + month);
};
System.out.println(quarter);
JEP 359: Records (预览) (Java 14) 和 JEP 384: Records (第二次预览) (Java 15):
正式作为Java语言特性之前,Records在Java 14和15中作为预览特性出现,用于简化数据类的声明。
// Record预览特性示例
record User(String name, int age) { }
User user = new User("Alice", 30);
System.out.println(user.name()); // 输出: Alice
模式匹配的instanceof (Java 16):
Java 16引入了模式匹配的instanceof,它增强了instanceof操作符,使得类型检查和类型转换更加简洁。
// 模式匹配的instanceof示例
Object obj = "Java";
if (obj instanceof String s && s.length() > 2) {
System.out.println(s)
}
向量API (Incubator) (Java 16):
Java 16引入了向量API作为Incubator模块,这是一个用于表达向量计算的API,可以充分利用现代处理器的SIMD(单指令多数据)指令。这个API仍在孵化阶段,意味着它在将来的版本中可能会有所变化。
// 向量API示例(Incubator模块,可能需要添加--add-modules jdk.incubator.vector)
IntVector vector = IntVector.fromArray(IntVector.SPECIES_256, new int[] {1, 2, 3, 4, 5, 6, 7, 8}, 0);
IntVector addedVector = vector.add(vector);
int[] resultArray = addedVector.toArray();
System.out.println(Arrays.toString(resultArray)); // 输出:[2, 4, 6, 8, 10, 12, 14, 16]
外部函数和内存API (Incubator) (Java 16):
Java 16引入了外部函数和内存API(Foreign Function & Memory API)作为Incubator模块,它提供了一个可以与本地代码更安全交互的API,此API在未来的版本中也可能会有所变化。
// 外部函数和内存API示例(Incubator模块,可能需要添加--add-modules jdk.incubator.foreign)
try (MemorySegment segment = MemorySegment.allocateNative(100)) {
MemoryAddress baseAddress = segment.baseAddress();
// 使用MemoryAddress进行内存操作
}
强化的伪随机数生成器 (Java 17):
Java 17增强了伪随机数生成器,提供了对多种新的随机数生成器的支持。
// 使用强化的伪随机数生成器
RandomGenerator generator = RandomGenerator.of("Xoshiro256PlusPlus");
System.out.println(generator.nextInt());
模式匹配的switch (预览) (Java 17):
Java 17引入了模式匹配的switch作为预览特性,这个特性在Java中引入了更复杂的模式匹配,能够简化代码并提高其可读性。
// 模式匹配的switch示例(预览特性,可能需要添加--enable-preview)
String formatted = switch (obj) {
case Integer i -> String.format("int %d", i);
case Long l -> String.format("long %d", l);
case Double d -> String.format("double %f", d);
case String s -> String.format("String %s", s);
default -> obj.toString();
};
System.out.println(formatted);
密封类 (Sealed Classes) (Java 17):
Java 17将密封类和接口引入为正式特性,它们限制了可以扩展或实现的类和接口的数量,这有助于提供更精确的类型系统。
// 密封类特性示例
public sealed interface Shape permits Circle, Rectangle {
// 接口定义
}
public final class Circle implements Shape {
// 类定义
}
public non-sealed class Rectangle implements Shape {
// 类定义
}
持久化的数据结构 (Java 18):
Java 18引入了一些新的集合API,它们是持久化的,也就是说,它们在修改时不会更改原有的数据结构,而是创建新的结构。
// 持久化数据结构示例
List<Integer> list = List.of(1, 2, 3);
List<Integer> newList = list.with(4); // 创建一个包含新元素的新列表
System.out.println(newList); // 输出:[1, 2, 3, 4]