为什么要推荐Java11?
因为它的效率。
原来Gauva中的一些实用特性,在Java11中有;
C#中早就支持了的var,在Java11中也有;
HttpClent也得到极大的简化,并且支持HTTP2.0;
G1已经被设置为默认GC;
并加入新的性能卓越的ZGC;
.....
没有对比,就没有伤害。
先从一个简单的需求,对比使用以前的版本和Java8到11的版本实现代码的差别。
需求:
往集合中存放5个值“1,2,3,4,5”,并输出所有小于3的值
-
实现代码
这个简单的需求,原来需要10行左右的代码。Java11,只需要两行(代码看不明白没关系,文章继续往下看)。
书中自有黄金屋 书中自有颜如玉。
学习的过程,也是你不断发现惊喜提升效率的过程。
10分钟时间过一遍这几个版本比较实用的一些新特性,本文只负责入门,深入使用的请参阅官方API。
一、Java8
-
Lambdas表达式
可谓日盼夜盘终于盼来了的语法糖。
基本语法:
(parameters) -> expression
或
(parameters) ->{ statements; }
上面图片中的例子,就是使用了Lambdas表达式,简化了循环操作。
现在,从头开始写个例子:
定义一个集合(var、List.of为Java11新特性,为了演示效果使用):
var list = List.of(1,2,3,4,5,6);
需求:对集合进行遍历
原来的写法:
for(var i : list){
System.out.println(i);
}
使用Lambdas:
list.stream().forEach((var i) -> {
System.out.println(i);
});
你可以简化下:
list.stream().forEach(i -> {
System.out.println(i);
});
再简化下:
list.stream().forEach(i -> System.out.println(i));
还能简化下:
list.stream().forEach(System.out::println);
顺便提下stream()、parallelStream() 两者的区别,前者是串行,即一个个的处理。后者是并行,即多线程处理。
如果你已经看明白了Lambdas表达式,就去API或者网上寻找它的更深入用法吧。
-
接口静态、默认方法
Java8开始,允许接口添加静态和默认方式,两者都不需要实现类实现。
静态方法,使用static关键字修饰,不可被继承。
默认方法,使用default关键字修饰,可被继承,可被重写。
如下:
default void defaultMethod(){
System.out.println("默认方法");
}
static void staticMethod(){
System.out.println("静态方法");
}
二、Java9(非长期维护版本)
-
HTTP/2
-
集合加强
三、Java10(非长期维护版本)
-
var 类型判断
四、Java11
Java11,作为Java8以后的首个长期维护版本,包含了8,9,10的全部实用新特性,广受好评。关于流传的收费问题,下面会介绍。
-
var 变量类型判断
var关键字可以自动推断变量的类型,但是注意,它跟JavaScript里面的var不同,它是静态的,变量类型一旦被编译器确定以后,不可修改。
了解下它具体的使用
String text = "hello world"; // Java 8
var v_text = "hello world"; // Java 11
Java10以前,变量的类型必须明确指定,现在,可以使用var关键字,由编译器去推断当前类型。
var v_int = 1;
v_int = 2; // 正确
v_int = "one"; // 编译无法通过。用var声明的变量仍然是静态类型的。 不兼容的类型无法重新分配给此类变量。
有了这个变量,每天敲代码的效率得可以提升5个百分点,你觉得呢。
-
String 新增方法
String新增部分方法,可简化String操作。可参照下面代码。
var text = " hello world ";
text.isBlank(); // 是否为空,输出false
text.strip(); // 去除首尾空格,输出“hello world”
text.stripTrailing(); // 去除尾部空格,输出“ hello world”
text.stripLeading(); // 去除首部空格,输出“hello world ”
text.repeat(2); // 字符串copy,输出“ hello world hello world ”
text.lines().count(); // 行数,输出1
text = " hello \n world ";
text.lines().count(); // 行数,输出2
-
集合新增方法
(List/ Set/ Map)都添加了 of 和 copyOf 方法,它们两个都用来创建不可变的集合
示例
var list = List.of("hello","world"); // .of() 从给定的参数创建了一个新的不可变列表
var copyList = List.copyOf(list); // .copyOf() 创建列表的不可变副本
System.out.println(list == copyList);// true
var map = Map.of("key1","value1","key2","value2");
var copyMap = Map.copyOf(map);
var set = Set.of(1,2);
var copySet = Set.copyOf(set);
强调,of创建的集合,不可改变。
-
InputStream 新增方法
本次新增方法:transferTo(),这个我平时用的不多,但是这次新增的方法,确实很实用,可以用来将数据直接传输到 OutputStream。
示例
var classLoader = ClassLoader.getSystemClassLoader();
var inputStream = classLoader.getResourceAsStream("source.txt");
var target = File.createTempFile("target", ".txt",new File("F://temp/"));
var outputStream = new FileOutputStream(target);
inputStream.transferTo(outputStream);
-
HttpClient
Java总算是出一个官方版,好用的HttpClient。。。支持HTTP1.1、HTTP2.0,并支持同步、异步调用。
示例
var request = HttpRequest.newBuilder()
.version(HttpClient.Version.HTTP_2) // Http版本HTTP_2、HTTP_1_1
.timeout(Duration.ofMinutes(2)) // 超时时间
.uri(URI.create("http://httpbin.org/post")) // 请求URL
// .GET() // 请求方式,默认GET,POST使用:POST()
.POST(HttpRequest.BodyPublishers.ofString("hello world.")) // BodyPublishers定义作为请求主体发送的数据类型,如字符串,字节数组,文件或输入流
.build();
var client = HttpClient.newBuilder().build();
// 同步调用
var response = client.send(request,HttpResponse.BodyHandlers.ofString());
System.out.println("同步调用返回结果:" + response.body());
// 异步调用
client.sendAsync(request, HttpResponse.BodyHandlers.ofString())
.thenApply(HttpResponse::body)
.thenAccept(System.out::println)
.join();
-
收费问题
相信大家都对这个问题很感兴趣,我简单介绍下。
JDK 可以分为三类,OpenJDK、OracleJDK、其他家JDK。Java11 OracleJDK和OpenJDK基本完全一致。其他家JDK基本都是根据OpenJDK开发编译
如果你是个人开发者。这些JDK对你都是免费使用的。
如果你是公司,OracleJDK在未来是收取费用的。但是在OracleJDK的下载页面上,有Oracle编译的OpenJDK,它和OracleJDK目前没什么区别。
当然,也可以选择其他JDK,推荐使用:
Zulu OpenJDK
基本全部基于OpenJDK编译,也会参与OpenJDK的fix,但是都会先推送到OpenJDK再编译到自己的JDK中。
下载地址:
https://www.azul.com/downloads/zulu/
博客内所有文章,每周从公众号同步一次。
文章源码均可从公众号获取。
如果您可以关注下,那就好了。