从 Java8 降级到 Java17 的 7 个理由
原文地址: 7 Reasons to Migrate from Java 8 to Java 17
开释吧,Java 的全副力量。[手动狗头]
简介
从 Java8 到 Java18,Java 曾经经验了漫长的倒退历程(Java20 非长期保护版本)。同时也是从 Java 8 开始,Java 生态系统产生了许多变动。其中最显著的变动是 Java 版本公布节奏的扭转。Java 8 于 2014 年公布,而 Java 17 则是在 2021 年公布的,这两个版本之间相差了 7 年的工夫。然而,2017 年 9 月,Java 平台的主架构师 Mark Reinhold 收回提议,要求将 Java 的性能更新周期从之前的每两年一个新版本缩减到每六个月一个新版本。该提议取得了通过,并在提出后不久失效。因而对于 Java 生态系统的开发者而言,能够更快的应用上 Java 最新的版本性能。
如果你像我一样,曾经应用了很长时间的 Java 8,并且感觉本人须要学习 Java 的新性能,那么这篇文章就是为你筹备的。
从 Java8 开始,有许许多多的新性能被增加到了 JDK 中,然而很显著不是所有的性能都有用,好用,受大家的欢送。所以,我在本文中列出了从 Java8 开始最受 Java 程序员欢送的性能,你能够将本文作为一个学习的参考,同时,学会了能够找你共事吹吹牛逼。
要害性能
1.Local Variable Type Inference[局部变量类型推断]
局部变量类型推断 能够说是 Java8 以来增加的最受欢迎的性能了,它容许你在不指定类型的状况下申明局部变量。理论代码执行时候的类型是通过表达式右侧的内容推断进去的,该性能也称之为 var 类型。(没错,逐步 Js 化)。
例如:var a = 1
Java8 应用局部变量
URL url = new URL("https://www.baidu.com");
System.out.println(url.getClass());
Java10 有了局部变量类型推断后
var url = new URL("https://www.baidu.com");
System.out.println(url.getClass());
下面的代码最终的输入是齐全一样的,然而很显著,在 Java10 当前不须要申明具体的局部变量类型。
ps: Java8 中 lombok 提供了相似的性能,也是 var,只不过须要导包。
import lombok.var; import org.junit.jupiter.api.Test; import java.net.MalformedURLException; import java.net.URL; // 应用 lombok public class JdkTests { @Test public void test1() throws MalformedURLException {var url = new URL("https://www.baidu.com"); System.out.println(url.getClass()); } }
2.switch expression[switch 表达式加强]
在 Java 14 中应用 switch 表达式时,你不用应用 break 关键字来跳出 switch 语句,也不用在每个 switch case 上应用 return 关键字来返回一个值;相同,你能够返回整个 switch 表达式。这种加强的 switch 表达式使整个代码看起来更洁净,更容易浏览。
Java8 中应用 switch
int flag = 1;
switch(flag) {
case 1:
System.out.println("hello");
break;
case 2:
System.out.println("world");
break;
case 3:
System.out.println("hello world");
break;
case 4:
System.out.println("hello");
break;
default:
System.out.println("haha");
}
Java14 后应用 switch
int flag = 1;
switch(flag) {case 1,4 -> System.out.println("hello");
case 2 -> System.out.println("world");
case 3 -> System.out.println("hello world");
default -> System.out.println("haha");
}
3.Text blocks[文本块]
文本块是 Java 15 中呈现的一个新个性,它容许你在不应用本义符号的状况下创立多行字符串。在代码中写 Json 并且还想换行的时候就十分难受。通过上面的例子,你能够看到如果应用了文本块,代码会变得如许的简洁和难受。
Java8 中
String json = "{\n" +
""id": 3,\n"+" "username": "fake_data",\n"+" "password": "fake_data",\n"+" "ips": [\n"+" "fake_data"\n"+"],\n"+" "firstLoginTime": 29,\n"+" "lastLoginTime": 69,\n"+" "failedAttempts": 62,\n"+" "lockedUntil": "2013-11-20 20:23:23"\n"+"}";
Java15 之后
String json = """{"id": 3,"username":"fake_data","password":"fake_data","ips": ["fake_data"],"firstLoginTime": 29,"lastLoginTime": 69,"failedAttempts": 62,"lockedUntil":"2013-11-20 20:23:23"}""";
System.out.println(json);
4.Records[record 类]
record 类是 Java14 引入的一个新的申明类的形式(之前之后 class)。通过该关键字你能够用更少的代码创立一个相似于 POJO 的类(害,就是个一般的 Java 类,譬如 User 类,Student 类等,或者叫实体类也行,不须要分的很粗疏)。相较于以往,在此之前大多数开发者应用 Lombok 来简化 POJO 类的写法(不须要写 get set 之类),但当初,应用了 record,你不须要应用任何第三方库,就能够将代码写的更加简洁。在上面的例子中,你能够看到用 record 代码会如许的简洁。
Java8
public class User {
private String name;
private String password;
public User() {}
public User(String name, String password) {
this.name = name;
this.password = password;
}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public String getPassword() {return password;}
public void setPassword(String password) {this.password = password;}
}
Java8 应用 lombok
@AllArgsConstructor
@NoArgsConstructor
@Data
public class User {
private String name;
private String password;
}
应用 record
public record User(String name,String password) {}
测试代码
@Test
public void test7() {User user = new User("2","3");
System.out.println(user.name());
}
5.Pattern matching for instanceof[instanceof 模式匹配]
instanceof 模式匹配是 Java 16 中退出的一个新个性。它容许你将 instanceof 操作符作为一个表达式来应用,并返回被转换的对象(不须要强转了)。在解决嵌套的 if-else 语句时十分有用。在上面的例子中,你能够看到咱们是如何应用 instanceof 操作符来 return Employee 对象的,而不应用强转。
Java8
if (obj instanceof Employee){Employee emp = (Employee)obj;
return emp.getName();}
应用 instanceof 模式匹配
if (obj instanceof Employee emp){return emp.getName();
}
6.Sealed classes[密封类]
关闭类是 Java 17 中退出的一个新个性。它容许你将一个类或接口的继承限度在一组无限的子类中。简略来说就是,你有一个 UserService 接口,只想要被 UserServieImpl 实现,以前是不能限度的,当初有了 Sealed classes 个性之后就能够了,那么具体如何做到呢?
通过 sealed 修饰符来形容某个类为密封类,同时应用 permits 关键字来制订能够继承或实现该类的类型有哪些。留神 sealed 能够润饰的是类 (class) 或者接口(interface),所以 permits 关键字的地位应该在 extends 或者 implements 之后。
例子:
应用 sealed 申明一个 UserService 只可能被 UserServiceImpl,UserServiceFinalImpl 实现。
public sealed interface UserService permits UserServiceImpl, UserServiceFinalImpl{}
想要实现 sealed 申明的接口(继承类也一样),子类,或者实现类,须要用 final 或者 non-sealed 润饰。
public final class UserServiceFinalImpl implements UserService{
}
public non-sealed class UserServiceImpl implements UserService{}
下面两者的区别在于:
final 润饰的实现类不能被进一步继承,而一个 non-sealed 润饰的实现类能够被进一步继承。
// 进一步继承
public class UserServiceImplNonSealed extends UserServiceImpl{}
7.Useful NullPointerException
NullPointerExceptions 是 Java 14 中退出的一个新性能。它容许你取得更多对于 NullPointerExceptions 的信息。这在你调试 NullPointerExceptions 时十分有用。在上面的例子中,你能够看到同样的代码在 Java 8 和 Java 14 中产生了不同的 NullPointerExceptions,但在 Java 14 中,你能够失去更多对于异样的信息。(看到更多的异样栈信息,可能更好的进行 bug 定位)
小结
本文中我还没有涵盖 Java 17 以来减少的所有性能,但我曾经涵盖了最受欢迎的性能。如果你想理解更多对于 Java 的新性能,那么我倡议你去看看上面提供的链接。
References
- JDK 10 features — https://openjdk.org/projects/jdk/10/
- JDK 11 features — https://openjdk.org/projects/jdk/11
- JDK 12 features — https://openjdk.org/projects/jdk/12
- JDK 13 features — https://openjdk.org/projects/jdk/13
- JDK 14 features — https://openjdk.org/projects/jdk/14
- JDK 15 features — https://openjdk.org/projects/jdk/15
- JDK 16 features — https://openjdk.org/projects/jdk/16
- JDK 17 features — https://openjdk.org/projects/jdk/17