当前位置:   article > 正文

“爆炸性更新!JDK 17携全新语法特性强势来袭,开发者必看的升级亮点“(1)_jdk17新玩法

jdk17新玩法

找往期文章包括但不限于本期文章中不懂的知识点:

个人主页:我要学编程(ಥ_ಥ)-CSDN博客

所属专栏:Java进化论

目录

背景 

yield关键字 

var关键字 

空指针异常 

密封类

接口中的私有方法

instanceof关键字


背景 

Java 8 虽然曾经是使用最广泛的版本,但由于它不再是受支持的版本(除非通过付费支持计划),很多公司已经开始或完成了向 Java 11 或 Java 17 的迁移。

需要注意的是,具体使用哪个版本可能因公司而异,一些公司可能因为特定的技术需求、框架兼容性、成本因素或内部政策而选择停留在某个版本。然而,趋势是向着最新的 LTS 版本迁移,以获取最新的安全补丁、性能提升和新功能。

上面是 AI对 有关Java17是否会成为以后常用的开发版本 的看法。也许在不久的将来就会代替Java11成为新的常用开发版本,因此我们程序员也要开始学习Java17的相关语法变动。

下面是官方对Java17的相关改动。

yield关键字 

我们要想在多种不同情况下,返回不同的值,会用 switch 语句来解决。

例如:用一个 ret 来接收不同情况的值。

  1. public class Test {
  2. public static void main(String[] args) {
  3. int n = 1;
  4. int ret = 0;
  5. switch (n) {
  6. case 1:
  7. ret = 1;
  8. break;
  9. case -1:
  10. ret = -1;
  11. break;
  12. case 0:
  13. ret = 0;
  14. break;
  15. }
  16. System.out.println(n);
  17. }
  18. }

上面是正常的 switch 语句,下面来看简写版的 switch 语句。

  1. public class Test {
  2. public static void main(String[] args) {
  3. int n = 1;
  4. // 不能使->两边的值全部一样
  5. int ret = switch (n) {
  6. case 1 -> 1;
  7. case -1 -> -1;
  8. case 0 -> 0;
  9. default -> 100;
  10. };
  11. System.out.println(n);
  12. }
  13. }

注意:switch 语句中 -> 两边的值不能全部一样。如果上面的代码把 default 语句去掉的话,那么就会出现语法错误。下面是代码的结果:

如果不想使用指向符 -> 可以使用yield来代替:

  1. public class Test {
  2. public static void main(String[] args) {
  3. int n = 1;
  4. // 不能使->两边的值全部一样
  5. int ret = switch (n) {
  6. case 1 : yield 1;
  7. case -1: yield -1;
  8. case 0: yield 0;
  9. default: yield 100;
  10. };
  11. System.out.println(n);
  12. }
  13. }

注意:这里也和上面一样,不能出现全部一样的。

简化之后的 -> 其后可以跟着代码块,并且把 yield 关键字当成 return 使用。

  1. Class Test {
  2. public static void main(String[] args) {
  3. int number = 4;
  4. // 不能使->两边的值全部一样
  5. int result = switch (number) {
  6. case 1 -> 1;
  7. case 2 -> 2;
  8. case 3 -> 3;
  9. case 4 -> {
  10. System.out.println("It's a four!");
  11. yield 4; // 使用yield关键字从代码块返回一个值
  12. }
  13. default -> 1;
  14. };
  15. System.out.println(result); // 输出: It's a four! 和 40
  16. }
  17. }

相对来说,我们平时都是写的完整版的switch语句,所以这个更新我们了解即可。 

var关键字 

从Java10开始,var关键字就开始被引入了。其功能就是使我们的代码更加简洁!如下所示:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 顺序表模拟实现二维数组
  4. ArrayList<ArrayList<Integer>> list = new ArrayList<>();
  5. }
  6. }

但是如果我们要用顺序表模拟实现三维甚至是四维数组呢?难道也是用一个一个的去实现吗?所以Java10 开始就引入了var 关键字,实现对类型的简化。如下所示:

  1. public class Test {
  2. public static void main(String[] args) {
  3. // 顺序表模拟实现二维数组
  4. ArrayList<ArrayList<Integer>> list = new ArrayList<>();
  5. // 根据后面的泛型推导前面的 var 是个啥
  6. var list2 = new ArrayList<ArrayList<Integer>>();
  7. }
  8. }

其实这个与泛型的有点类似,泛型是根据前面的类型来推导后面的类型是个啥,而 var 是根据我们写后面的类型来推导我们的类型是个啥。 

但凡事都有两面性,既然可以方便我们简写类型,那么也就有要注意的地方: 

1. 不能用来声明字段。

2. 不能用来声明方法参数。

3. 不能用来声明方法的返回类型。

4. var声明的变量必须初始化,并且不能初始化为null。

其实也挺好理解的。首先,得把第四点给理解了:为啥 var声明的变量必须初始化 ?因为我们是通过后面的初始化内容来推导前面的类型的。如果不初始化,就不能推导出前面的类型是个啥?同理:你把 引用数据类型 初始化为null,那么编译器又怎么根据后面的内容推导出前面是个啥呢?Integer?String?还是自定义类型呢?

第四点知道了,其余的也就都理解了。我们学过字段是会被默认初始化的。如果是基本数据类型倒还好,但如果是引用数据类型呢?还是会被初始化为null。但这里可能有小伙伴有疑问:把字段全部初始化不就行了嘛?即使没意义但初始化的时候也不影响啊。举个很简单的例子:我们在实现自定义的链表时,如果链表的头被初始化了,那么我们怎么判断这个链表是否为空呢?因此,var不能用来声明字段。同理:方法的参数和返回类型是我们事先确定的。但是如果使用var的话,就代表我们事先是不确定的,这就互相矛盾了。

空指针异常 

对于空指针异常的抛出,Java 8 只会给出哪里抛出了空指针异常,而没有把为什么会出现空指针异常告诉我们。Java 17就改善了这个方面。下面给出了两者对于空指针的异常的抛出示例:

Java 8 :

Java 17 : 

密封类

当我们使用关键字 final 去修饰一个类时,这个被修饰的类就变成完全封闭的状态了,不存在有类可以继承它,那么这个类就被称为密封类。密封类一般应用在类和接口中,对接口和类的实现和继承进行约束。 JDK17提供了一个新的关键字: sealed 。密封类除了可以被该关键字 sealed 修饰之外,还可以在声明这个关键词的末尾用 permits 表示要开放给哪些类型来继承。如下所示:

根据不同的需求,处理上面的方式也不同:

1、把Dog类也加上 sealed 限制 ,并且同样要开放给其他类。也就说,Dog类也是有继承限制的。

2、如果Dog类想成为最后一级类的话(就是不想还有其他类继承Dog类的话),只能用关键字 non-sealed 和 final 修饰。这两种修饰的意义不同:non-sealed 修饰代表的是这个类没有限制,也就类似于开放这个类的意思;而 final 修饰代表的是这个类不可被继承的类。其实也就是处理两种极限问题:可以让所有类继承它,没有类能够继承它。

注意:sealed 修饰的类一定要有子类。因为我们会在修饰的这个类的末尾声明上可以继承它的类,因此sealed修饰的类一定是会有子类的。

同样这个继承也是可以实现多个的:

  1. sealed abstract class Animal permits Dog{
  2. public String name;
  3. public int age;
  4. public Animal(String name, int age) {
  5. this.name = name;
  6. this.age = age;
  7. }
  8. public abstract void eat();
  9. }
  10. sealed class Dog extends Animal permits PetDog{
  11. public Dog(String name, int age) {
  12. super(name, age);
  13. }
  14. @Override
  15. public void eat() {
  16. System.out.println(name+" 正在吃狗粮~");
  17. }
  18. }
  19. non-sealed class PetDog extends Dog{
  20. public PetDog(String name, int age) {
  21. super(name, age);
  22. }
  23. }

接口中的私有方法

Java 8以前的Java版本,所有的接口只能是抽象方法。但从Java 8开始接口中可以有默认方法

被实现,以及静态方法被实现。

从Java 9 开始,进一步允许在接口中定义私有方法和私有静态方法的实现。 

总结:Java 17 中可以有私有的静态方法和私有的方法,以及默认的方法它们的实现。 

instanceof关键字

instanceof关键字,我们前面在学习多态时,使用来判断 某个对象是否为该类型(或者其子类)的一个实例。

现在对其改进的效果如下:

  1. if (obj instanceof String) {
  2. String str = (String)obj;
  3. .......
  4. }

上面的instanceof语法一共做了三件事:

1. 判断是否为String类型;

2. 如果是,转成String类型;

3. 创建一个名为str 的临时变量来接收转换的结果; 

也就是说,下面的代码和上面的代码的效果是一样的:

  1. // obj是否为String类型,如果是创建临时变量str
  2. if (obj instanceof String str) {
  3. }

还有更多关于Java 17的更新知识,我们会随着学习的深入,继续开始学习。好啦!本期  “爆炸性更新!JDK 17携全新语法特性强势来袭,开发者必看的升级亮点“(1)的学习之旅就到此结束啦!我们下一期再一起学习吧!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/899925
推荐阅读
相关标签
  

闽ICP备14008679号