Java 11简介

栏目: Java · 发布时间: 7年前

内容简介:本教程涵盖了Java 9到11中最重要的语言和API特性。Java 10引入了一个新的语言关键字var,它可以在声明局部变量时替换类型信息(本地意味着方法体内的变量声明)。

本教程涵盖了 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进行POST。类似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);
// true

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


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

创建不可变map时,你不必自己创建map条目,而是将键和值作为参数传递:


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

Java 11中的不可变集合仍然使用旧Collection API中的相同接口。但是,如果尝试通过添加或删除元素来修改不可变集合,则抛出java.lang.UnsupportedOperationException。

幸运的是,如果你尝试改变不可变集合,Intellij IDEA会通过检查发出警告。

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


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

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


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]

Optionals

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


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

String字符串

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


" ".isBlank(); // true
" Foo Bar ".strip(); // "Foo Bar"
" Foo Bar ".stripTrailing(); // " Foo Bar"
" Foo Bar ".stripLeading(); // "Foo Bar "
"Java".repeat(3); // "JavaJavaJava"
"A\nB\nC".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);
}

以上所述就是小编给大家介绍的《Java 11简介》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Pro JavaScript Design Patterns

Pro JavaScript Design Patterns

Dustin Diaz、Ross Harmes / Apress / 2007-12-16 / USD 44.99

As a web developer, you’ll already know that JavaScript™ is a powerful language, allowing you to add an impressive array of dynamic functionality to otherwise static web sites. But there is more power......一起来看看 《Pro JavaScript Design Patterns》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

SHA 加密
SHA 加密

SHA 加密工具

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具