Java8-19新特性一览 ,认识全新的前沿技术_java目前比较新的技术

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

Java8-19新特性一览 ,认识全新的前沿技术

前言

Java8出来这么多年后已经成为企业最成熟稳定的版本相信绝大部分公司用的还是这个版本但是一眨眼今年Java19都出来了相信很多Java工程师忙于学习工作对新特性没什么了解有的话也仅限于某一块。


本篇就是博主对自己感觉有用的新特性做了一个案例验证及简要说明整合起来分享给大家。


特别说明Java17是继Java8之后的一个重要里程碑像SpringBoot3.0、IDEA2022、Jenkins新版、Kafka4.0等等很多生态都强制绑定支持这个版本等于是给它背书博主建议大家有必要花时间去了解一下。


你的收获

首先你能通过一篇简单、连续、直观的文章就明白Java8之后Java未来整体发展的趋势为之后几年适应Java相关工作打下基础


其次你可以通过了解Java9-17的新特性为以后的面试加分毕竟一个爱学习有态度的程序员会更受企业青睐


最后你可以看看博主对Java未来发展趋势的粗浅看法也许能给迷茫的你带来收获。


Java发展趋势

最后稍微说下不少人关心的这个问题我觉得只要你了解过Java8之后这些版本的新特性和预览特性你一定可以发现Java在尝试改变这是一个很好的信号。


就比如上面的这些新特性你甚至能找到不少Python、JavaScript等语言的影子Go语言作为新语言就是站在巨人肩膀上发展起来的吸纳了很多语言的优秀特点。


现在Java也在走类似的路能明显看到它在将一些优秀语言的亮点容纳到自己的新版本中这种趋势代表着一个意义Java在不断进步。


网上一直充斥着一些看衰Java的言论没必要当真你必须自己去体会生态和了解国内的IT公司动态才能有所感受。


Java依然是国内使用最广泛的语言并且具备最庞大的生态这不是一朝一夕可以替代的是市场规律发展的结果。


SpringBoot3.0支持Java17Jenkins新版支持Java17Kafka4.0直接抛弃Java8ElasticSearch8.x最低支持JDK17还有IDEA2022默认支持Java17等等之类的开源社区和生态都在给新版的Java背书更有微软宣布全面拥抱Java这里面不单单是技术层面的提高更有利益的诉求和捆绑。


从这一点来说学习Java完全是值得的作为一门成熟优秀且严谨的语言它就像一个白领一样正襟危坐。


我还认为现在学习和掌握Java的工程师未来转去其他语言也不会有压力上面的新特性就说明了这种方向它在吸纳其他语言的亮点。


未来可以预期的是你转到其他语言会逐渐变的没有那么陌生和晦涩这是我看到的一个方向未来的编程语言发展大方向就是 大融合 你中有我我中有你学一门通所有。


准备工作

首先你要安装Java17版本环境变量配置还是和以前没区别这是我的版本。

在这里插入图片描述

其次建议安装IDEA2022.3新版IDEA占用内存比以前少很多而且有一些增强支持。

在这里插入图片描述

安装好后需要做一个对Java17的配置看图。

setting配置

在这里插入图片描述

Project Structure配置

在这里插入图片描述

这里特别说明一下最好选择预览版本因为Java17包含一些预览功能这里不选预览版本会编译报错。

在这里插入图片描述
在这里插入图片描述


新特性

一共分为了8个按照版本顺序来讲述的最后一个是因为几个版本连续有增强所以单独拿出来。

1、接口private

1、说明

Java9新特性在接口中声明private方法不会被外部实现。

2、案例

声明一个接口一个default方法两个private方法。

/**
 * <p>
 * 用户信息接口
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 15:03
 */
public interface UserInterface {
   private void getUsername() {
      System.err.println("你好我是java");
   }

   private void getPassword() {
      System.err.println("你好我是python");
   }

   default void getData() {
      getUsername();
      getPassword();
   }
}

实现这个接口可以看到只能实现default方法无法实现private方法。

/**
 * <p>
 * JDK9新特性接口private方法
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 15:10
 */
public class UserImpl implements UserInterface {

   @Override
   public void getData() {
      UserInterface.super.getData();
   }

   public static void main(String[] args) {
      UserImpl user = new UserImpl();
      user.getData();
   }
}

Ctrl+Insert可以查看要实现的方法

3、注意

private接口自动是default的所以要有方法体否则编译不通过。


2、类型推断

1、说明

Java11新特性在方法内部用var关键字声明一个属性或对象可以被编译器自动判断类型。

2、案例

案例包含两个测试一个是直接测试var声明的变量是否能自己推断类型一个是在循环中使用的效果。

/**
 * <p>
 * JDK11新特性类型推断
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 11:52
 */
public class TypeInferenceTest {

   public static void main(String[] args) {
      TypeInferenceTest Test = new TypeInferenceTest();
      // 测试类型推断
//    Test.testVar();

      // 循环中使用
      List<UserInfo> userList = new ArrayList<>();
      UserInfo userInfo = new UserInfo();
      userInfo.setUsername("张三");
      userInfo.setPassword("123456");
      userList.add(userInfo);
      for (var user : userList) {
         System.err.println(user.getUsername() + " | " + user.getPassword());
      }
   }

   public void testVar() {
      var name = "张三";
      var age = 33;
      var id = 1001L;
      var amount = BigDecimal.ZERO;
      var user = new UserInfo();
      System.err.println("-------------------------------------------------");
      System.err.println(name);
      System.err.println(age);
      System.err.println(id);
      System.err.println(amount);
      System.err.println(user);
   }

   public static class UserInfo {
      private String username;
      private String password;

      public String getUsername() {
         return username;
      }

      public void setUsername(String username) {
         this.username = username;
      }

      public String getPassword() {
         return password;
      }

      public void setPassword(String password) {
         this.password = password;
      }
   }
}
3、注意

1、只能在方法内部使用局部变量

2、必须有初始化值且不能为null

3、不能定义为方法的返回类型。


3、空指针优化

1、说明

Java15新特性就是把NullPointerException异常的日志做了优化打印的更人性化。

2、案例

可以看到提示会更有指向性意味着以后在复杂的生产环境排错过程中你很可能不会再被空指针异常所困扰。

3、注意

没什么可注意的


4、文本块

1、说明

JDK15新特性就是替代了以前String中一堆换行符和双引号的简洁版写法相信你很难不喜欢。

2、案例

可以看到就是三引号取代了双引号因为双引号的内容会夹带一堆换行符而三引号里面就单纯是内容很清晰而且双引号换行需要杠n而三引号直接换行即可生效。

/**
 * <p>
 * JDK15新特性文本块
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 23:36
 */
public class TextBlockTest {
   private static final String str =
         "佛点击退还给我热负荷给你你国防科技你看你看都发给你开发理念赶快来过年回来寡\n"
         + "\n"
         + "了金佛Joe大肥腿可劲儿几天了人家烤肉饭 考虑到福奈特"
         + " 肯定会发给客户的风格来证明自己的实力。";

   private static final String newStr = """
            开发读后感我交电话费国际化等方面高端客户发光飞碟挺乖的发过火等方面
            你发的哭给你看多方面的索菲特荣
            卡密电脑版福克斯麻烦了圣诞老人new没人大四吗开发机会大煞风景
            点很可能付款单。
         """;

   public static void main(String[] args) {
      System.err.println(str);
      System.err.println("------------------------------------------------");
      System.err.println(newStr);
   }
}
3、注意

文本块只有一个要注意的地方就是默认三引号内的内容没有缩进想要缩进的话要以末尾三引号为参照物向后偏移来确定缩进量。


5、智能转型

1、说明

Java16新特性就是帮你对instanceof做了增强智能转换变量类型。

2、案例

可以对比old和new两种写法第二种就是将第一种简化了类型转换+声明变量+后续逻辑判断一起搞定。

/**
 * <p>
 * JDK16新特性智能转型
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 14:02
 */
public class InstanceofMatching {
   /**
    * 旧写法
    * @param obj 未知对象
    */
   static void testOld(Object obj) {
      if (obj instanceof String) {
         String s = (String) obj;
         if ("模式匹配".equals(s)) {
            System.err.println(s);
         }
      }
   }

   /**
    * 新写法
    * @param obj 未知对象
    */
   static void testNew(Object obj) {
      if (obj instanceof String s && "模式匹配".equals(s)) {
         System.err.println(s);
      }
   }

   public static void main(String[] args) {
      testOld("Hello, Java!");
      testNew("模式匹配");
   }
}
3、注意

instanceof后面若需要增强判断必须要用&&不能用||因为instanceof本来就是做类型匹配的Java可以确保&&后面的变量一定存在但无法判断||后面的变量一定存在所以会报错。


6、record类

1、说明

Java16新特性简单讲就是有了它声明一个final类变得更简洁和可读。

2、案例

先来看下写法

/**
 * <p>
 * JDK16新特性record类
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 21:52
 */
public record RecordTest(int type, String typeName) {
   private void test() {
      System.err.println(type + " | " + typeName);
   }
   public static void main(String[] args) {
      // 这里new的时候带的参数其实就是类的属性等于声明属性+访问构造方法二合一。
      RecordTest recordTest = new RecordTest(100, "葡萄牙");
      recordTest.test();
   }
}

上面的新写法等同于下面这种老的写法一看就懂。

/**
 * <p>
 * RecordTest的写法等同于这个类
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 21:55
 */
public final class RecordCustomTest {
   final int type;
   final String typeName;

   public int type() {
      return type;
   }

   public String name() {
      return typeName;
   }

   public RecordCustomTest(int type, String typeName) {
      this.type = type;
      this.typeName = typeName;
   }

   @Override
   public boolean equals(Object o) {
      if (this == o)
         return true;
      if (o == null || getClass() != o.getClass())
         return false;
      RecordCustomTest that = (RecordCustomTest) o;
      return type == that.type && Objects.equals(typeName, that.typeName);
   }

   @Override
   public int hashCode() {
      return Objects.hash(type, typeName);
   }
}
3、注意

没什么可注意的就跟使用正常的类差不多只是自动生成了以下内容


1、括号里的参数就是该类的属性且是final类型

2、自动生成一个带有该属性的构造器

3、自动生成该属性的访问器如xx.type()、xx.typeName()

4、生成了equals和hashCode方法。


如果还是不懂就理解成lombok中的@Data注解即可同样的意思。


7、密封类和接口

1、说明

Java17新特性密封类和密封接口。

使用sealed关键字声明的类可以通过设置permits关键字来控制哪些子类可以继承它。

使用sealed关键字声明的接口可以通过设置permits关键字来控制哪些类可以实现它。。

简单来讲就是爸爸规定哪个儿子能继承财产。

2、案例

看下密封类的写法

用sealed声明一个类设置permits授权哪几个子类可以继承它。

/**
 * <p>
 * JDK17新特性密封类
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 17:20
 */
public sealed class Daddy permits Son1, Son2 {
}

第一个儿子可以继承

/**
 * <p>
 *
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 17:22
 */
public final class Son1 extends Daddy {
}

第二个儿子可以继承

/**
 * <p>
 *
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 17:23
 */
public final class Son2 extends Daddy {
}

第三个儿子估计是不孝子

可以看到IDEA是有错误提示的意思是没有被sealed声明的父类所允许。

然后我们来看看密封接口。

其实和密封类差不多但还可以结合前面讲过的record来简化代码。

/**
 * <p>
 * JDK17新特性密封接口
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 18:03
 */
public sealed interface DaddyInterface permits Son4, Son5 {
   void test();
}

第四个儿子可以实现父亲的愿望用了record之后简化了变量声明及一些内置方法的实现。

/**
 * <p>
 *
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 17:23
 */
public record Son4(int age, String name) implements DaddyInterface {
   @Override
   public void test() {

   }
}

第五个儿子可以实现父亲的愿望

/**
 * <p>
 *
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 17:23
 */
public record Son5(int age, String name) implements DaddyInterface {
   @Override
   public void test() {

   }
}

第六个儿子有点傻不能实现父亲的愿望可以看到错误提示和前面密封类一样。

3、注意

1、sealed声明的父类它的子类只能用final、sealed、non-sealed来修饰

2、sealed声明的父类至少要有一个子类

3、没有在permits中授权的子类无法继承父类

4、密封接口和密封类的注意点没什么区别

4、密封接口结合record来完成可以少写更多代码变得更加简洁。


这里特别说一点sealed和record其实在Java新特性模式匹配中很有意义但是我认为模式匹配对于从未了解过的Java程序员来讲有些晦涩结合sealed后有种套娃传销的感觉如果难于理解就不是我们本来的目的因此没有专门花费章节赘述结尾会简单说一下我对模式匹配的看法。


8、switch增强

1、说明

为什么把switch单独放最后讲因为Java14-17分别对其做了增强放在最后汇总起来讲更直观。

一共有三个改变

1、支持箭头语法

2、支持表达式

3、支持case null。

2、案例

箭头语法其实就是把旧写法中的冒号和break直接换成了箭头来代替更简洁。

/**
 * <p>
 * JDK14新特性switch箭头语法
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 11:05
 */
public class SwitchTest1 {
   private static void pcs(int i) {
      switch (i) {
         case 1:
            System.err.println("Mac book Pro 2021");
            break;
         case 2:
            System.err.println("Mac book Pro 2022");
            break;
         default:
            System.err.println("Mac book ");
      }
   }

   private static void computer(int i) {
      switch (i) {
         case 1 -> System.err.println("Mac book Pro");
         case 2 -> System.err.println("外星人");
         default -> System.err.println("苹果");
      }
   }

   public static void main(String[] args) {
      pcs(1);
      computer(3);
   }
}

支持表达式其实就是能写单个或多个表达式来return。

/**
 * <p>
 * JDK14新特性switch支持表达式
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 11:05
 */
public class SwitchTest3 {

   /**
    * 单表达式
    */
   private static String computer(int i) {
      return switch (i) {
         case 1 -> "Mac book Pro";
         case 2 -> "外星人";
         default -> "苹果";
      };
   }

   /**
    * 多表达式
    */
   private static String computerNew(int i) {
      return switch (i) {
         case 1, 2 -> {
            System.err.println("---------libin9ioak-----------");
            System.err.println("来一个Mac book Pro");
            yield "Mac book Pro来咯";
         }
         case 3, 4 -> {
            System.err.println("---------libin9ioak-----------");
            System.err.println("来一个外星人");
            yield"外星人来咯";
         }
         default -> {
            System.err.println("---------libin9ioak-----------");
            System.err.println("没的选就来个苹果吧");
            yield "苹果来咯";
         }
      };
   }

   public static void main(String[] args) {
//    System.err.println(computer(2));
//    System.err.println(computer(3));

      System.err.println(computerNew(2));
      System.err.println(computerNew(4));
      System.err.println(computerNew(5));
   }
}

支持case null其实就是case可以接收null值了。

/**
 * <p>
 * JDK17新特性(预览)switch支持case null
 * </p>
 *
 * @author libin9ioak
 * @Date 2022/10/24 11:05
 */
public class SwitchTest2 {
   private static void pcs(String s) {
      if (s == null) {
         return;
      }
      switch (s) {
         case "1":
            System.err.println("Mac book Pro 2021");
            break;
         case "2":
            System.err.println("Mac book Pro 2022");
            break;
         default:
            System.err.println("Mac book ");
      }
   }

   private static void computer(String s) {
      switch (s) {
         case "1" -> System.err.println("Mac book Pro");
         case null -> System.err.println("null");
         default -> System.err.println("苹果");
      }
   }

   public static void main(String[] args) {
      pcs("1");
      computer(null);
   }
}

可以看下效果直接传null也不会报错。

3、注意

1、箭头语法冒号和箭头不能同时存在

2、表达式多个表达式时要使用花括号并使用yield关键字返回

3、case null是预览功能在IDEA - Project Structure - Modules中选择Language Level为17(Preview)才能编译通过参考前面的准备工作。


总结

1、Java9-19的新特性不仅于此还有一些挺有特点的内容比如不可变集合、模块化、String和Stream的API增强等等但是我个人认为不具有代表性要么是工具能直接帮你转换要么就是你大概率用不到所以就没列出来


2、模式匹配是不少Java程序员关注的内容本篇中record、switch、密封类和接口的内容其实都是模式匹配的基础但模式匹配对Java来讲并不成熟《Thinking In Java》的作者也说过可能要好几年才会看到完整形式的Java模式匹配所以没必要现在就花太多心思去研究一个残缺版本这个特性和Python、Kotlin、Scala相比其实还差得远。


结语

如果这篇文章对您有所帮助或者有所启发的话求一键三连点赞、评论、收藏➕关注您的支持是我坚持写作最大的动力。

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java