Java 11教程

当前位置:

Java 11教程

作者:邓华锋于2018-9-27发布在 分类:java / 阅读26 次 / 共有0条评论  

Java 11即将来临,许多人仍在使用Java 8进行生产。这个示例驱动的教程涵盖了Java 9到11中最重要的语言和API特性。没有文本墙,所以让我们直接进入代码。请享用!

局部变量类型推断

Java 10引入了一个新的语言关键字var,它可以在声明局部变量时替换类型信息(本地意味着方法体内的变量声明)。

在Java 10之前,您将声明如下变量:

String text = "Hello Java 9"; 

现在,您可以替换String使用var编译器从变量的赋值中推断出正确的类型。在这种情况下text是类型String

var text = "Hello Java 10"; 

声明的变量var仍然是静态类型。您无法将不兼容的类型重新分配给此类变量。此代码段无法编译:

var text = "Hello Java 11"; text = 23; // Incompatible types 

您还可以final结合使用var禁止将变量重新分配给另一个值:

final var text = "Banana"; text = "Joe"; // Cannot assign a value to final variable 'text' 

var当编译器无法推断出正确的变量类型时,不允许这样做。以下所有代码示例都会导致编译器错误:

// Cannot infer type: var a; var nothing = null; var lambda = () -> System.out.println("Pity!"); var method = this::someMethod; 

局部变量类型推断确实涉及泛型。在下一个示例中,current有一个相当冗长的类型Map<String, List<Integer>>,可以简化为单个var关键字,从而节省您输入大量样板:

var myList = new ArrayList<Map<String, List<Integer>>>(); for (var current : myList) { // current is infered to type: Map<String, List<Integer>> System.out.println(current); } 

从Java 11开始var,lambda参数也允许使用关键字,这使您可以为这些参数添加注释:

Predicate<String> predicate = (@Nullable var a) -> true; 

提示:在Intellij IDEA中,您可以将鼠标悬停在变量上,同时CMD/CTRL显示变量的感应类型(按键盘爱好者按下CTRL + J)。

HTTP客户端

Java 9引入了一个HttpClient用于处理HTTP请求的新的API。从Java 11开始,这个API现在是最终的,可以在标准库包中找到java.net让我们来探索一下我们可以用这个API做些什么。

新的HttpClient可以同步或异步使用。同步请求会阻止当前线程,直到响应可用。BodyHandlers定义响应体的预期类型(例如,字符串,字节数组或文件):

var request = HttpRequest.newBuilder() .uri(URI.create("https://winterbe.com")) .GET() .build(); var client = HttpClient.newHttpClient(); HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); 

可以异步执行相同的请求。调用sendAsync不会阻塞当前线程,而是返回一个CompletableFuture构造异步操作管道。

var request = HttpRequest.newBuilder() .uri(URI.create("https://winterbe.com")) .build(); var client = HttpClient.newHttpClient(); client.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body) .thenAccept(System.out::println); 

我们可以省略.GET()调用,因为它是默认的请求方法。

下一个示例通过发送数据到给定的URL POSTBodyHandlers习惯使用它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 

集合

诸如的集合ListSet并且Map已经用新方法扩展。List.of从给定的参数创建了一个新的不可变列表。List.copyOf创建列表的不可变副本。

var list = List.of("A", "B", "C"); var copy = List.copyOf(list); System.out.println(list == copy); // true 

因为list已经是不可改变的有没有实际需要实际创建列表实例的一个副本,因此listcopy是相同的实例。但是,如果你复制一个可变列表,copy确实是一个新实例,所以它保证在改变原始列表时没有副作用:

var list = new ArrayList<String>(); var copy = List.copyOf(list); System.out.println(list == copy); // false 

创建不可变映射时,您不必自己创建映射条目,而是将键和值作为交替参数传递:

var map = Map.of("A", 1, "B", 2); System.out.println(map); // {B=2, A=1} 

Java 11中的不可变集合仍然使用旧Collection API中的相同接口但是,如果尝试通过添加或删除元素来修改不可变集合,java.lang.UnsupportedOperationException则抛出a。幸运的是,如果你尝试改变不可变集合,Intellij IDEA会通过检查发出警告。

Streams是在Java 8中引入的,现在有三种新方法。Stream.ofNullable从单个元素构造流:

Stream.ofNullable(null) .count() // 0 

方法dropWhiletakeWhile都接受谓词来确定从流中放弃哪些元素:

Stream.of(1, 2, 3, 2, 1) .dropWhile(n -> n < 3) .collect(Collectors.toList()); // [3, 2, 1] Stream.of(1, 2, 3, 2, 1) .takeWhile(n -> n < 3) .collect(Collectors.toList()); // [1, 2] 

如果您还不熟悉Streams,那么您应该阅读我的Java 8 Streams Tutorial

选配

Optionals还会收到一些非常方便的新方法,例如,您现在可以简单地将选项转换为流,或者为空选项提供另一个可选的后备:

Optional.of("foo").orElseThrow(); // foo Optional.of("foo").stream().count(); // 1 Optional.ofNullable(null) .or(() -> Optional.of("fallback")) .get(); // fallback 

字符串

最基本的类之一String获取一些辅助方法来修剪或检查空格以及流式传输字符串的行:

" ".isBlank(); // true " Foo Bar ".strip(); // "Foo Bar" " Foo Bar ".stripTrailing(); // " Foo Bar" " Foo Bar ".stripLeading(); // "Foo Bar " "Java".repeat(3); // "JavaJavaJava" "AnBnC".lines().count(); // 3 

InputStreams

最后但并非最不重要的是,InputStream最终获得了一种非常有用的方法来将数据传输到一个OutputStream在处理原始数据流时非常常见的用例。

var classLoader = ClassLoader.getSystemClassLoader(); var inputStream = classLoader.getResourceAsStream("myFile.txt"); var tempFile = File.createTempFile("myFileCopy", "txt"); try (var outputStream = new FileOutputStream(tempFile)) { inputStream.transferTo(outputStream); } 

其他JVM功能

这些是 - 在我看来 - 从Java 8迁移到11时最有趣的语言新API功能。但是功能列表并没有在这里结束。最新的Java版本中包含了更多内容:

你最喜欢的功能是什么?让我知道

然后去哪儿?

许多人(包括我)仍在使用Java 8进行生产。但是,从2019年初开始,对JDK 8的免费支持就此结束所以现在是迁移到Java 11的好时机。我写了一篇迁移指南,介绍如何从Java 8 迁移到11,希望能帮助您完成迁移。您还应该阅读我的Java 8Stream API教程,以了解更多现代Java基础知识。本教程的源代码发布在GitHub上,所以请随意使用它(如果你愿意,可以留下一个明星)。您还应该在Twitter上关注我,以获取更多与Java和开发相关的内容。干杯!

  • 标签: java 11 教程
  • 该日志于 2018-9-27 18:08 由 邓华锋 发表在 邓华锋 上,你除了可以发表评论外,还可以转载"Java 11教程"日志到你的网站或博客,但是请保留源地址及作者信息,谢谢!!
  • 版权所有:《邓华锋》 => 《Java 11教程
    本文地址:http://dhf.ink/post-328.html
    除非注明,文章均为 《邓华锋》 原创,欢迎转载!转载请注明本文地址,谢谢。