前几天,JDK 14 正式发布了,此次发布的新版本一共包含了16个新的特性。html
其实,从Java8 到 Java14 ,真正的改变了程序员写代码的方式的特性并很少,咱们这篇文章就来看一下都有哪些。java
Lambda 表达式是 Java 8 中最重要的一个新特性,Lambda 容许把函数做为一个方法的参数。程序员
lambda 表达式的语法格式以下:sql
(parameters) -> expression
或
(parameters) ->{ statements; }复制代码
如如下例子:数据库
// 1. 不须要参数,返回值为 5
() -> 5
// 2. 接收一个参数(数字类型),返回其2倍的值
x -> 2 * x
// 3. 接受2个参数(数字),并返回他们的差值
(x, y) -> x – y
// 4. 接收2个int型整数,返回他们的和
(int x, int y) -> x + y
// 5. 接受一个 string 对象,并在控制台打印,不返回任何值(看起来像是返回void)
(String s) -> System.out.print(s)复制代码
Lambda表达式具备简洁、容易进行并行计算、是将来的编程趋势等优势,但同时也会带来调试困难,新人理解成本高等缺点。express
除了Lambda 表达式外,Java 8中还引入了Stream API,这使得Java终于进入到函数式编程的行列中来了。编程
Stream 使用一种相似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。api
Stream API能够极大提升Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。安全
以下图,就是经过Stream API对集合进行了一系列的操做:函数式编程
List<String> strings = Arrays.asList("Hollis", "HollisChuang", "hollis", "Hello", "HelloWorld", "Hollis");
Stream s = strings.stream().filter(string -> string.length()<= 6).map(String::length).sorted().limit(3)
.distinct();复制代码
并且,Stream还支持并行流,在性能上比传统的for循环要好不少。(详细用法:《Java 8中处理集合的优雅姿式——Stream》)
从Lambda表达式和Stream API问世至今,已经有6年的时间了,相信不少人已经在工做中使用过这些特性了。
虽然对于这两种语法的使用,不少人持有不一样的见解,可是做者仍是认为这个功能是十分好用的,只是在平常写代码的时候不要过度"炫技"使用超长的流式操做,代码可读性不要过低就能够了。
在Java 8以前,日期时间 API 存在诸多问题,如:Date非线程安全、java.util和java.sql的包中都有日期类、日期类并不提供国际化,没有时区支持。
因此,Java 8经过发布新的Date-Time API (JSR 310)来进一步增强对日期与时间的处理。
新的java.time包涵盖了全部处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操做。
常见操做以下:
// 获取当前的日期时间
LocalDateTime currentTime = LocalDateTime.now();
System.out.println("当前时间: " + currentTime);
// 时间比较
LocalDate today = LocalDate.now();
LocalDate date1 = LocalDate.of(2014, 01, 14);
if(date1.equals(today)){}
// 时间增长
LocalTime time = LocalTime.now();
LocalTime newTime = time.plusHours(2); // adding two hours复制代码
可是说实话,Java8中的时间API做者平常工做中用的比较少,主要是有不少历史代码,仍是依赖Date等类型,使用新的API就要面临互相转换问题。
在Java 10以前版本中,咱们想定义定义局部变量时。咱们须要在赋值的左侧提供显式类型,并在赋值的右边提供实现类型:
MyObject value = new MyObject();复制代码
在Java 10中,提供了本地变量类型推断的功能,能够经过var声明变量:
var value = new MyObject();复制代码
本地变量类型推断将引入“var”关键字,而不须要显式的规范变量的类型。
其实,所谓的本地变量类型推断,也是Java 10提供给开发者的语法糖。虽然咱们在代码中使用var进行了定义,可是对于虚拟机来讲他是不认识这个var的,在java文件编译成class文件的过程当中,会进行解糖,使用变量真正的类型来替代var(我反编译了Java 10的本地变量类型推断)
在JDK 12中引入了Switch表达式做为预览特性。并在Java 13中修改了这个特性,引入了yield语句,用于返回值。
而在以后的Java 14中,这一功能正式做为标准功能提供出来。
在之前,咱们想要在switch中返回内容,仍是比较麻烦的,通常语法以下:
int i;
switch (x) {
case "1":
i=1;
break;
case "2":
i=2;
break;
default:
i = x.length();
break;
}复制代码
在JDK13中使用如下语法:
int i = switch (x) {
case "1" -> 1;
case "2" -> 2;
default -> {
int len = args[1].length();
yield len;
}
};复制代码
或者
int i = switch (x) {
case "1": yield 1;
case "2": yield 2;
default: {
int len = args[1].length();
yield len;
}
};复制代码
在这以后,switch中就多了一个关键字用于跳出switch块了,那就是yield,他用于返回一个值。和return的区别在于:return会直接跳出当前循环或者方法,而yield只会跳出当前switch块。
Java 13中提供了一个Text Blocks的预览特性,而且在Java 14中提供了第二个版本的预览。
text block,文本块,是一个多行字符串文字,它避免了对大多数转义序列的须要,以可预测的方式自动格式化字符串,并在须要时让开发人员控制格式。
咱们之前从外部copy一段文本串到Java中,会被自动转义,若有一段如下字符串:
<html>
<body>
<p>Hello, world</p>
</body>
</html>复制代码
将其复制到Java的字符串中,会展现成如下内容:
"<html>\n" +
" <body>\n" +
" <p>Hello, world</p>\n" +
" </body>\n" +
"</html>\n";复制代码
即被自动进行了转义,这样的字符串看起来不是很直观,在JDK 13中,就可使用如下语法了:
"""
<html>
<body>
<p>Hello, world</p>
</body>
</html>
""";复制代码
使用"""做为文本块的开始符合结束符,在其中就能够放置多行的字符串,不须要进行任何转义。看起来就十分清爽了。
如常见的SQL语句:
String query = """
SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`
WHERE `CITY` = 'INDIANAPOLIS'
ORDER BY `EMP_ID`, `LAST_NAME`;
""";复制代码
看起来就比较直观,清爽了。
Java 14 中便包含了一个新特性:EP 359: Records,
Records的目标是扩展Java语言语法,Records为声明类提供了一种紧凑的语法,用于建立一种类中是“字段,只是字段,除了字段什么都没有”的类。经过对类作这样的声明,编译器能够经过自动建立全部方法并让全部字段参与hashCode()等方法。这是JDK 14中的一个预览特性。
使用record关键字能够定义一个记录:
record Person (String firstName, String lastName) {}复制代码
record 解决了使用类做为数据包装器的一个常见问题。纯数据类从几行代码显著地简化为一行代码。(详见:Java 14 发布了,不使用”class”也能定义类了?还顺手要干掉Lombok!)
以上,就是从Java 8 到 Java 14中,新推出的可能会影响开发人员写代码的方式的一些主要特性。
不知道你们有没有发现,最近几个版本中推出的一些功能,使得Java和Kotlin等语言愈来愈像了...
新的这些功能,确实在必定程度上能够简化一些代码,使得开发过程当中更加高效,可是说实话,尚未好到足够吸引广大开发者抛弃Java 8进行大规模迁移!
仍是那句话:版本任你发,我用Java 8;可是新特性咱们仍是要去了解下的。