smallyu的博客

smallyu的博客

马上订阅 smallyu的博客 RSS 更新: https://smallyu.net/atom.xml

Java 11 教程(译)

2018年10月31日 10:20

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);...

剩余内容已隐藏

查看完整文章以阅读更多