关于java:女同事问我JDK8以后有哪些新特性给我整不会了

女同事:咱们之前用的java8,当初改用Java11,相比是有哪些新个性么?
我:哦,咱们是为了进步和其余子系统程序的兼容性稳固,才进步了JDK版本。
女同事:喔?那就是说你不晓得有哪些新个性呗。
我:(😳😳??你们00后思路都这么清晰吗)咳咳,嗯,我只略知一二;
女同事:那你给我说说呗,我可想晓得了呢~
我:没问题~走,先干饭去。(独门绝技:饭遁)

  一提到JDK8的新个性,你可能就会联想到Lambda、函数式接口、Stream、Optional以及日期工夫API加强等等;

  诚然,这些都是咱们日常在应用的个性了。然而你没在意的是JDK曾经默默更新到JDK16了(均匀6个月一版),并且在过几个月就JDK17了哈哈哈!唉,真是菜的令人头大。

  前两天粉丝群的同学在分享面试题时,我看到面试题中包含:请说一下JDK8到JDK11都有哪些新个性?。我一惊,都卷成这吊样子了?

  尽管我也在用JDK11然而我对新个性还停留在JDK8。。到底是咱们老了还是卷不过年轻人了?😳😳上面是我总结各版本JDK的一些个性,看看你有哪些不晓得吧。

在这里插入图片形容

  本文咱们梳理一些在日常编程中能用到的一些新个性,或者你会发现新大陆,赶快更新本人的代码吧~~当然,上线保护的代码尽量就别改了,你懂得。

车票

JDK9(2017年9月)
    9-1、实例工厂办法
    9-2、接口里能够增加公有办法
    9-3、改良 try-with-resources
    9-4、多版本兼容 jar 包
    9-5、加强了钻石操作符 `<>`,能够在匿名外部类中应用了。
    9-6、加强了JDK8个性
JDK10(2018年3月)
    10-1、局部变量的主动类型推断(var)
    10-2、增强版Optional
Java 11(2018年9月)
    11-1、Lambda 中应用` var`
    11-2、字符串 API 加强
    11-3、javac + java 命令归一化
JDK 12(2019年3月)
    12-1、Switch表达式
    12-2、instanceof + 类型强转一步到位
JDK 13(2019年9月)
    13-1、文本块(Text Block)的反对
    13-2、加强 switch 语法:
JDK14(2020年3月)
    14-1、新增 Record 类
    14.2、新增 jpackage 打包工具
JDK15(2020年9月)
    15-1、ZGC 和 Shenandoah 两款垃圾回收器正式登陆
    15-2、关闭(Sealed)类
JAVA 16(2021年3月)
小结

JDK9(2017年9月)
9-1、实例工厂办法

  借助Java 9的一项新性能,即汇合工厂办法,咱们能够轻松地应用预约义的数据创立不可变的汇合。只须要在特定汇合类型上应用of办法。

List<String> fruits = List.of("apple", "xiaomi", "13xiang");
Map<Integer, String> numbers = Map.of(1, "one", 2,"two", 3, "three");
Set<String> colors = Set.of("yellow", "red", "baoqiang");

  在Java 9之前,咱们想要创立一个不可变的汇合,须要先创立一个可变汇合,而后应用 unmodifiableSet 创立不可变汇合,显然是很麻烦的。

public List<String> fruits() {
 List<String> fruitsTmp = new ArrayList<>();
 fruitsTmp.add("apple");
 fruitsTmp.add("xiaomi");
 fruitsTmp.add("13xiang");
 return Collections.unmodifiableList(fruitsTmp);
}

public Map<Integer, String> numbers() {
 Map<Integer, String> numbersTmp = new HashMap<>();
 numbersTmp.put(1, "one");
 numbersTmp.put(2, "two");
 numbersTmp.put(3, "three");
 return Collections.unmodifiableMap(numbersTmp);
}

public Set<String> setStr() {
Set<String> colors = new HashSet<>();
colorsTmp.add("A");
colorsTmp.add("B");
colorsTmp.add("C");

colorsTmp = Collections.unmodifiableSet(colors);
System.out.println(colorsTmp);
 return colorsTmp;
}

  同样,仅从ArrayList对象表创立即可应用Arrays.asList(…)method。

public List<String> fruitsFromArray() {
 String[] fruitsArray = {"apple", "xiaomi", "13xiang"};
 return Arrays.asList(fruitsArray);
}

举荐浏览:
Java中高级外围常识全面解析、Java高并发编程详解、阿里亿级高并发零碎设计、阿里巴巴Java性能调优实战(2021版)、凤凰架构 构建牢靠的大型分布式系统

9-2、接口里能够增加公有办法

  基于JAVA 8 对接口减少了默认办法的反对,在 JAVA 9 中对该性能进一步降级,能够在接口里定义公有办法,并且能够在默认办法里调用接口的公有办法。

ublic interface testInterface {

String test();

// 接口默认办法
default String defaultTest() {
    staticTest();
    return "default";
}

private String privateTest() {
    System.out.println("private method staticTest");
    return "static";
}

9-3、改良 try-with-resources

  Java 9 中不须要在 try 中额定定义一个变量。Java 9 之前须要这样应用 try-with-resources:

InputStream inputStream = new StringBufferInputStream("陈哈哈");
try (InputStream in = inputStream) {
    in.read();
} catch (IOException e) {
    e.printStackTrace();
}

  在 Java 9 中能够在try中间接应用 inputStream 变量,不须要再额定定义新的变量了。

InputStream inputStream = new StringBufferInputStream("一二");
try (inputStream) {
    inputStream.read();
} catch (IOException e) {
    e.printStackTrace();
}

9-4、多版本兼容 jar 包

  Java 9 中反对在同一个 JAR 中保护不同版本的 Java 类和资源。
9-5、加强了钻石操作符 <>,能够在匿名外部类中应用了。

  其实JAVA 5 就引入了泛型(generic),到了 JAVA 7 开始反对钻石(diamond)运算符,<>,能够主动推断泛型的类型。

在 Java 9 之前,外部匿名类须要指定泛型类型,如下:

List<Integer> numbers = new ArrayList<Integer>() {
}

而在 Java 9 中,能够主动做类型推导,如下:

List<Integer> numbers = new ArrayList<>() {
}

9-6、加强了JDK8个性

  加强了JDK8的个性如:Stream,Optional,Process API
JDK10(2018年3月)
10-1、局部变量的主动类型推断(var)

var a = "Hello, Java 10";
System.out.println(a);

  JAVA 10 带来了一个很有意思的语法var,它能够主动推断局部变量的类型,当前再也不必写类型了,也不必靠 lombok 的 var 注解加强了

  不过这个只是语法糖,编译后变量还是有类型的,应用时还是思考下可维护性的问题。强调一下,var 关键字目前只能用于局部变量以及 for 循环变量申明中。
10-2、增强版Optional

  从Java 9和Java 10开始,有几种用于Optional的有用办法。其中最乏味的两个是orElseThrow和ifPresentOrElse。

  如果没有值,则应用该orElseThrow办法抛出NoSuchElementException。否则,它返回一个值。

public Person getPersonById(Long id) {
 Optional<Person> personOpt = repository.findById(id);
 return personOpt.orElseThrow();
}

  因而,咱们能够防止将带参数的if语句与isPresentmethod一起应用。

public Person getPersonByIdOldWay(Long id) {
 Optional<Person> personOpt = repository.findById(id);
 if (personOpt.isPresent())
  return personOpt.get();
 else
  throw new NoSuchElementException();
}

  第二种乏味的办法是ifPresentOrElse。如果存在一个值,它将应用该值执行给定的操作。否则,它将执行给定的基于空的操作。

public void printPersonById(Long id) {
 Optional<Person> personOpt = repository.findById(id);
 personOpt.ifPresentOrElse(
   System.out::println,
   () -> System.out.println("Person not found")
 );
}

  在Java 8中,咱们能够if-else间接与isPresent办法一起应用。

public void printPersonByIdOldWay(Long id) {
 Optional<Person> personOpt = repository.findById(id);
 if (personOpt.isPresent())
  System.out.println(personOpt.get());
 else
  System.out.println("Person not found");
}

Java 11(2018年9月)
11-1、Lambda 中应用var

public String sumOfString() {
 BiFunction<String, String, String> func = (var x, var y) -> x + y;
 return func.apply("abc", "efg");
}

11-2、字符串 API 加强

  Java 11 新增了 一系列字符串解决办法,例如:

// 判断字符串是否为空白、以及判空
" ".isBlank(); 
"".isEmpty(); 
" Java11 ".stripTrailing();  // " Java11"
" Java11 ".stripLeading();   // "Java11 "

11-3、javac + java 命令归一化

  以前编译一个 java 文件时,须要先 javac 编译为 class,而后再用 java 执行,当初能够放到一起执行了,香啊!

$ java HelloWorld.java
Hello Java 11!

JDK 12(2019年3月)
12-1、Switch表达式

  咱们能够定义多个case标签并应用箭头返回值,称之为:应用case L ->箭头标签的switch。

  此性能自JDK 12起可用。它使Switch表达式真正更易于拜访。

public String newSwitch(int day) {
      return switch (day) {
          case 1, 2, 3 -> "摸鱼工作日";
          case 4 -> "小周五";
          case 5, 6, 7 -> "休息日";
          default -> "invalid";
      };
  }

如下代码:

newSwitch(1);
newSwitch(4);
newSwitch(6);

后果如下:

摸鱼工作日
小周五
休息日

举荐浏览:
Java中高级外围常识全面解析、Java高并发编程详解、阿里亿级高并发零碎设计、阿里巴巴Java性能调优实战(2021版)、凤凰架构 构建牢靠的大型分布式系统

而对于低于12的Java,雷同的示例要简单得多。

public String oldSwitch(int day) {
        switch (day) {
            case 1:
            case 2:
            case 3:
                return "摸鱼工作日";
            case 4:
                return "小周五";
            case 5:
            case 6:
            case 7:
                return "休息日";
            default:
                return "invalid";
        }
    }

  对于咱们休息日和小周五的定义是不是感觉阵阵蒙圈?别意外,在咱们的SQL大腿群中,小周五和周五曾经成为了每周的传统节日,值的庆贺~~

在这里插入图片形容
12-2、instanceof + 类型强转一步到位

  之前解决动静类型碰上要强转时,须要先 instanceof 判断一下,而后再强转为该类型解决:

Object obj = "Hello Java 12!";
if (obj instanceof String) {
    String s = (String) obj;
    int length = s.length();
}

  当初 instanceof 反对间接类型转换了,不须要再来一次额定的强转:

Object obj = "Hello Java 12!";
if (obj instanceof String str) {
    int length = str.length();
}

JDK 13(2019年9月)
13-1、文本块(Text Block)的反对

  文本块是多行字符串文字,它防止应用转义序列,并以可预测的形式主动设置字符串格局。它还使开发人员能够管制字符串的格局。从Java 13开始,文本块可用作预览性能。它们以三个双引号(”””)结尾。让咱们看看咱们如何轻松地创立和格式化JSON音讯。

public String getNewPrettyPrintJson() {
    return """
           {
                "name": "chenhaha",
                "sex": "undefined"
           }
           """;
}

  创立Java 13之前的雷同JSON字符串要简单得多。

public String getOldPrettyPrintJson() {
     return "{\n" +
            "     \"name\": \"chenhaha\",\n" +
            "     \"sex\": \"undefined\"\n" +
            "}";
}

13-2、加强 switch 语法:

  JAVA 12 中尽管加强了 swtich 语法,但并不能在 -> 之后写简单的逻辑,JAVA 13 带来了 swtich更完满的体验,就像 lambda一样,能够写逻辑,而后再返回:

int j = newSwitch (day) {
    case 1, 2, 3 -> "摸鱼工作日";
    case 4 -> "小周五";
    case 5, 6, 7 -> "休息日";
    default      -> {
        var k = day.toString().length();
        var res = f(k);
        yield res;
    }
};

JDK14(2020年3月)
14-1、新增 Record 类

  从Java 14开始,引入了新的Record类。咱们定义Record类时,应用关键字record;

  应用Records能够定义不可变的纯数据类(仅限getter),也叫记录类。它会主动创立toString,equals和hashCode办法。实际上,只须要定义如下所示的字段即可。

public record Person(String name, int age) {}

  具备相似性能的类如record蕴含字段,构造函数,getter和toString,equals以及hashCode办法。

public class PersonOld {

private final String name;
private final int age;

public PersonOld(String name, int age) {
    this.name = name;
    this.age = age;
}

public String getName() {
    return name;
}

public int getAge() {
    return age;
}

@Override
public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || getClass() != o.getClass()) return false;
    PersonOld personOld = (PersonOld) o;
    return age == personOld.age && name.equals(personOld.name);
}

@Override
public int hashCode() {
    return Objects.hash(name, age);
}

@Override
public String toString() {
    return "PersonOld{" +
            "name='" + name + '\'' +
            ", age=" + age +
            '}';
}

14.2、新增 jpackage 打包工具

  新增 jpackage 打包工具,间接打包二进制程序,再也不必装 JRE 了!

  之前如果想构建一个可执行的程序,还须要借助三方工具,将 JRE 一起打包,或者让客户电脑也装一个 JRE 才能够运行咱们的 JAVA 程序。

  当初 JAVA 间接内置了 jpackage 打包工具,帮忙你一键打包二进制程序包,不必再乱折腾了。
JDK15(2020年9月)
15-1、ZGC 和 Shenandoah 两款垃圾回收器正式登陆

  在 JAVA 15中,ZGC 和 Shenandoah 再也不是试验性能,正式登陆了(不过 G1 依然是默认的)。如果你降级到 JAVA 15 当前的版本,就赶快试试吧,性能更强,提早更低。
15-2、关闭(Sealed)类

  应用密封类性能,能够限度超类的应用。应用new关键字,sealed能够定义哪些其余类或接口能够扩大或实现以后类。

public abstract sealed class Pet permits Cat, Dog {}

  容许的子类必须定义一个修饰符。如果不想容许任何其余扩展名,则须要应用final关键字。

public final class Cat extends Pet {}

  另一方面,你能够关上扩大类。在这种状况下,应应用non-sealed修饰符。

public non-sealed class Dog extends Pet {}

  当然,上面的可见申明是不容许的。

public final class Tiger extends Pet {}

JAVA 16(2021年3月)

  JAVA 16 在用户可见的中央变动并不多,根本都是 14/15 的实验性内容;
小结

  那么开发人员为什么还保持用Java8呢?

  或者是因为降级在代码和保护层面或多或少会呈现意想不到的BUG,很多企业求稳,领导们不愿随便改变。降级没问题的话领导倒是能多拿点儿提成,万一出了问题,领导能给你背锅??
在这里插入图片形容

  说回来程序员自身也不肯定有工夫去学习新个性和深刻了解新的技术个性,有点工夫多看看面试题它不香么?

  Java每三年会有一个长期反对的版本(Long Term Support release,简称LTS),该版本会提供为期三年的反对。Java 8是一个LTS,所以值得信赖。并且已根本被业内宽泛应用,而下一个LTS别离是Java11和Java17,Mark一下吧。

  然而,目前1线的java开发者中,应该还是大部分在应用Java8的版本。有数据统计 80% 的人还在用JDK8,甚至有的公司还在应用JDK7。

在这里插入图片形容

  问题来了?大家所用的Java版本是多少呢?

举荐浏览:
Java中高级外围常识全面解析、Java高并发编程详解、阿里亿级高并发零碎设计、阿里巴巴Java性能调优实战(2021版)、凤凰架构 构建牢靠的大型分布式系统

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理