女同事:咱们之前用的 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 版)、凤凰架构 构建牢靠的大型分布式系统