Java 11 教程(译)
Java 11已经发布,很多人还在使用Java 8。这篇教程讲述一些重要的语言特性和API。
局部变量类型推断
局部变量指在方法体内声明的变量。Java10就已经引进一个新的关键字var,用于代替在声明局部变量时候的类型声明。
在Java 10之前,你必须这样声明一个变量:
String text = "Hello Java 9";现在你可以使用var代替String。编译器会自动从变量的赋值推断出正确的类型。如文本的类型为String:
var text = "Hello Java 10";使用var声明的变量仍然是静态变量,不可以在声明后赋值为其它类型:
var text = "Hello Java11";text = 23; // 编译错误,不兼容的类型同样可以使用final声明变量为常量:
final var text = "Banana";text = "Joe"; // 编译错误当然,在编译器无法推断出类型的场景下,不可以使用var,比如这些情况:
var a;var nothing = null;var lamdba = () -> System.out.println("Pity!");var method = this::someMethod;当变量声明包含泛型时,var的优势尤为突出,下面的示例就用var来代替冗长的Map<String, List
var myList = new ArrayList<Map<String, List<Integer>>>();for (var current : myList) { // current 的类型会被推断为 Map<String, List<Integer>> System.out.println(current);}Java 11的var关键字同样支持在lamdba表达式的参数中使用,并且支持为这些参数添加注解:
Predicate<String> predicate = (@Nullable var a) -> true;小技巧:在Intellij IDEA中按住CTRL键可以查看变量的推断类型。
HTTP Client
从Java 9开始引进试用新的API HttpClient,用于处理HTTP请求。现在Java 11将其标准化,我们可以从模块java.net中获取使用。
新的HttpClient在同步和异步场景下都可以使用。同步请求会阻塞线程,直到获取到响应。BodyHandlers定义了响应数据的类型(如String、Byte[]、File)。
var request = HttpRequest.newBuilder() .uri(URI.create("https://blog.smallyu.net")) .GET() .build();var client = HttpClient.newHttpClient();var response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.body());// 记得在module-info.java中导入java.net.http模块同样可以使用异步的方式实现请求,调用sendAsync方法并不会阻塞当前线程,它会构建异步操作流,在接收到响应后执行相应操作:
var request = HttpRequest.newBuilder() .uri(URI.create("https://blog.smallyu.net")) .build();var client = HttpClient.newHttpClient();client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println);// 线程睡眠,防止在返回响应前当前线程就结束Thread.sleep(3000);.GET()方法会作为默认的请求方式。
下一个示例通过POST方式发送请求到指定URL。与BodyHandlers相似,使用BodyPublishers定义要发送的数据类型:
var request = HttpRequest.newBuilder() .uri(URI.create("https://postman-echo.com/post")) .header("Content-Type", "text/plain") .POST(HttpRequest.BodyPublishers.ofString("Hi there!")) .build();var client = HttpClient.newHttpClient();var response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.statusCode()); // 200最后一个示例演示了如何使用BASIC-AUTH执行权限验证:
var request = HttpRequest.newBuilder() .uri(URI.create("https://postman-echo.com/basic-auth")) .build();var client = HttpClient.newBuilder() .authenticator(new Authenticator() { @Override protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication("postman", "password".toCharArray()); } }) .build();var response = client.send(request, HttpResponse.BodyHandlers.ofString());System.out.println(response.statusCode()); // 200集合框架
集合框架如List、Set和Map都增加了新的方法。List.of方法根据给定参数创建一个不可变列表,List.copyOf创建一个已存在列表的副本。
var list = List.of("A", "B", "C");var copy = List.copyOf(list);System.out.println(list == copy);...剩余内容已隐藏