Java 9-11新特性
Java 9新特性
模块化系统(JPMS)
java
// module-info.java
module com.example.myapp {
requires java.sql; // 依赖其他模块
requires transitive java.logging; // 传递依赖
exports com.example.api; // 导出包
exports com.example.internal to com.example.test; // 限定导出
uses com.example.Service; // 使用服务
provides com.example.Service with com.example.ServiceImpl; // 提供服务
}JShell(交互式编程)
bash
# 启动JShell
jshell
# 交互式执行
jshell> int a = 10;
jshell> int b = 20;
jshell> a + b
$3 ==> 30
jshell> /exit接口私有方法
java
public interface MyInterface {
default void method1() {
privateMethod();
System.out.println("方法1");
}
default void method2() {
privateMethod();
System.out.println("方法2");
}
// 私有方法(Java 9+)
private void privateMethod() {
System.out.println("私有方法");
}
// 私有静态方法
private static void privateStaticMethod() {
System.out.println("私有静态方法");
}
}try-with-resources改进
java
// Java 9之前
InputStream is = new FileInputStream("test.txt");
try (InputStream stream = is) {
// 使用stream
}
// Java 9+:可以直接使用已声明的变量
InputStream is = new FileInputStream("test.txt");
try (is) {
// 使用is
}钻石操作符增强
java
// Java 9之前
Map<String, List<String>> map1 = new HashMap<String, List<String>>();
// Java 9+:匿名内部类也可以使用钻石操作符
Map<String, List<String>> map2 = new HashMap<>() {
@Override
public List<String> get(Object key) {
return super.getOrDefault(key, new ArrayList<>());
}
};Stream API增强
java
import java.util.stream.Stream;
import java.util.List;
import java.util.Optional;
public class Java9StreamDemo {
public static void main(String[] args) {
// takeWhile - 取元素直到条件不满足
Stream.of(1, 2, 3, 4, 5, 1, 2)
.takeWhile(n -> n < 4)
.forEach(System.out::print); // 1 2 3
// dropWhile - 丢弃元素直到条件不满足
Stream.of(1, 2, 3, 4, 5, 1, 2)
.dropWhile(n -> n < 4)
.forEach(System.out::print); // 4 5 1 2
// iterate - 带条件的迭代
Stream.iterate(1, n -> n < 10, n -> n + 1)
.forEach(System.out::print); // 1 2 3 4 5 6 7 8 9
// ofNullable - 创建可能为null的Stream
String str = null;
Stream.ofNullable(str)
.forEach(System.out::println); // 无输出
// Optional转Stream
Optional.of("Hello")
.stream()
.forEach(System.out::println);
}
}集合工厂方法
java
import java.util.List;
import java.util.Set;
import java.util.Map;
public class CollectionFactoryDemo {
public static void main(String[] args) {
// 创建不可变List
List<String> list = List.of("A", "B", "C");
// 创建不可变Set
Set<String> set = Set.of("A", "B", "C");
// 创建不可变Map
Map<String, Integer> map = Map.of(
"A", 1,
"B", 2,
"C", 3
);
// Map.entry创建Entry
Map<String, Integer> map2 = Map.ofEntries(
Map.entry("A", 1),
Map.entry("B", 2),
Map.entry("C", 3)
);
// 注意:这些都是不可变集合
// list.add("D"); // 抛出UnsupportedOperationException
}
}Optional增强
java
import java.util.Optional;
public class Java9OptionalDemo {
public static void main(String[] args) {
Optional<String> opt = Optional.of("Hello");
// or() - 为空时返回另一个Optional
Optional<String> result = Optional.<String>empty()
.or(() -> Optional.of("Default"));
System.out.println(result); // Optional[Default]
// ifPresentOrElse()
opt.ifPresentOrElse(
v -> System.out.println("值: " + v),
() -> System.out.println("无值")
);
// stream() - 转为Stream
opt.stream().forEach(System.out::println);
}
}Java 10新特性
var局部变量类型推断
java
import java.util.List;
import java.util.ArrayList;
public class VarDemo {
public static void main(String[] args) {
// 基本类型
var num = 10; // int
var price = 99.9; // double
var flag = true; // boolean
// 引用类型
var name = "Hello"; // String
var list = new ArrayList<String>(); // ArrayList<String>
var map = List.of(1, 2, 3); // List<Integer>
// 循环中使用
for (var i = 0; i < 10; i++) {
System.out.println(i);
}
for (var item : list) {
System.out.println(item);
}
// try-with-resources
try (var reader = new java.io.FileReader("test.txt")) {
// 使用reader
} catch (Exception e) {
e.printStackTrace();
}
}
}var限制
java
public class VarLimitations {
// 不能用于字段
// var field = 10; // 错误
// 不能用于方法参数
// public void method(var param) {} // 错误
// 不能用于方法返回类型
// public var get() { return 10; } // 错误
// 必须初始化
// var x; // 错误
// 不能赋值为null
// var x = null; // 错误
// 不能用于Lambda表达式
// var func = () -> {}; // 错误
}不可变集合增强
java
import java.util.List;
import java.util.Set;
import java.util.Map;
import java.util.Collections;
public class Java10CollectionDemo {
public static void main(String[] args) {
List<String> list = new ArrayList<>(List.of("A", "B", "C"));
// 复制为不可变集合
List<String> copy = List.copyOf(list);
Set<String> setCopy = Set.copyOf(Set.of("A", "B"));
Map<String, Integer> mapCopy = Map.copyOf(Map.of("A", 1));
// toUnmodifiableList/Set/Map
List<String> unmodifiable = list.stream()
.filter(s -> s.startsWith("A"))
.collect(java.util.stream.Collectors.toUnmodifiableList());
}
}Optional增强
java
import java.util.Optional;
public class Java10OptionalDemo {
public static void main(String[] args) {
Optional<String> opt = Optional.of("Hello");
// orElseThrow() - 无参版本
String value = opt.orElseThrow(); // 如果为空抛出NoSuchElementException
}
}Java 11新特性
String新方法
java
public class Java11StringDemo {
public static void main(String[] args) {
String str = " Hello World ";
// isBlank() - 是否为空白
System.out.println(" ".isBlank()); // true
System.out.println("".isBlank()); // true
// lines() - 按行分割
String multiline = "Line1\nLine2\nLine3";
multiline.lines().forEach(System.out::println);
// strip() - 去除首尾空白(比trim更智能)
System.out.println(str.strip()); // "Hello World"
System.out.println(str.stripLeading()); // "Hello World "
System.out.println(str.stripTrailing()); // " Hello World"
// repeat() - 重复字符串
System.out.println("Ab".repeat(3)); // AbAbAb
}
}文件读写增强
java
import java.nio.file.Files;
import java.nio.file.Path;
public class Java11FileDemo {
public static void main(String[] args) throws Exception {
Path path = Path.of("test.txt");
// 写入字符串
Files.writeString(path, "Hello, Java 11!");
// 读取字符串
String content = Files.readString(path);
System.out.println(content);
// 读取指定大小
String partial = Files.readString(path, java.nio.charset.StandardCharsets.UTF_8);
}
}Collection转数组
java
import java.util.List;
public class Java11CollectionDemo {
public static void main(String[] args) {
List<String> list = List.of("A", "B", "C");
// Java 11之前
String[] arr1 = list.toArray(new String[0]);
// Java 11+:更简洁
String[] arr2 = list.toArray(String[]::new);
}
}HTTP Client API(标准化)
java
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.http.HttpResponse.BodyHandlers;
public class Java11HttpClientDemo {
public static void main(String[] args) throws Exception {
HttpClient client = HttpClient.newHttpClient();
// GET请求
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/get"))
.GET()
.build();
HttpResponse<String> response = client.send(
request,
BodyHandlers.ofString()
);
System.out.println("状态码: " + response.statusCode());
System.out.println("响应体: " + response.body());
// POST请求
HttpRequest postRequest = HttpRequest.newBuilder()
.uri(URI.create("https://httpbin.org/post"))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString("{\"name\":\"test\"}"))
.build();
// 异步请求
client.sendAsync(request, BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
}
}运行Java文件
bash
# Java 11之前:需要先编译
javac HelloWorld.java
java HelloWorld
# Java 11+:直接运行
java HelloWorld.javaLambda参数类型推断
java
import java.util.function.BiFunction;
public class Java11LambdaDemo {
public static void main(String[] args) {
// Java 11+:Lambda参数可以使用var
BiFunction<Integer, Integer, Integer> add = (var a, var b) -> a + b;
// 可以添加注解
BiFunction<Integer, Integer, Integer> add2 =
(@Deprecated var a, var b) -> a + b;
}
}Java 9-11特性总结
| 版本 | 重要特性 |
|---|---|
| Java 9 | 模块化系统、JShell、接口私有方法、集合工厂方法 |
| Java 10 | var类型推断、不可变集合增强 |
| Java 11 | String新方法、HTTP Client、直接运行Java文件 |