第一章 JDK9 新特性
jdk9是新特性最多的,因为jdk8是一个稳定版本。
1、JDK9新特性概述
模块系统 (Module System) | Java9最大特性。它提供了类似于OSGI框架的功能,模块之间存在相互的依赖关系,可以导出一个公共的API,并且隐藏实现的细节。作用为减少内存的开销。 |
JShell和Jlink | JShel是交互式Java编程环境。允许开发者在命令行界面中快速编写和测试Java代 码。 Jlink用于生成自定义的Java运行时映像,可以包含或排除特定的模块。 |
不可变集合类工厂方法 | 可以更方便地创建不可变集合。 |
接口中的私有方法 | 接口可以包含私有方法。 |
try-with-resources改进 | 能够更好地处理异常和资源关闭。 |
平台日志API和服务 | 提供了新的平台日志API和服务。 |
垃圾回收器 | 新增了Shenandoah垃圾回收器,旨在提供更高效的垃圾回收。 |
2 、模块化系统
Java9之前的问题:
1.运行时间长(JVM需要加载rt.jar不管其中的类是否被classloader加载 ,而模块化可以根据 模块的需要加载程序运行需要的class)。
2.当代码库越来越大,创建复杂。
3.很难真正地对代码进行封装。
模块(module)的概念,其实就是package外再裹一层,不声明默认就是隐藏。 模块化使得代码组 织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。
模块化做到了:
模块化的主要目的在于减少内存的开销。
只须必要模块,而非全部jdk模块,可简化各种类库和大型应用的开发和维护。
改进 Java SE 平台,使其可以适应不同大小的计算设备。
改进其安全性,可维护性,提高性能。
jdk9模块化代码:
注意:导入外部的junit模块并使用,必须将当前模块导出。
3、JShell命令
基本使用 | |
定义方法,使用方法 | |
查看当前Session内代码片段 | /list |
查看当前Session变量 | /vars |
查看当前Session下的方法 | /methods |
使用jshell代码没有受检异常 | |
退出 | /exit |
4 、接口私有方法
public interface demo2 {/** jdk8之前接口中只允许有 公有静态常量和抽象方法* *///接口默认都是公有静态常量,也只能是共有静态常量//public static final int num=1;int num=1;//接口默认方法都是公有抽象方法//public abstract void method1();void method1();/** jdk8及其之后接口可以有静态方法和默认方法* */public static void method2(){//静态方法System.out.println("接口中的静态方法");}public default void method3(){//默认方法System.out.println("接口中的默认方法");}/** jdk9及其之后接口可以有私有方法* private void method4(){}* private static void method4(){}* * */private void method4(){System.out.println("接口中的私有方法");}
}
5 、钻石操作符使用升级
在jdk8中,如下代码是报错的
Comparator<Object> com = new Comparator<>() {
@Override
public int compare(Object o1, Object o2) {
return 0;
}
};
<>必须写类型。而在jdk9中,上述代码就不报错,这是对<>钻石运算符的一个升级。
6 、try 语句
Java 8 中,可以实现资源的自动关闭,但是要求执行后关闭的所有资源必须在try子句中初始化,否则编译不通过。
Java 9 中,用资源语句编写try将更容易,我们可以在try子句中使用已经初始化过的资源,此时的资源是final的。
7 、String 存储结构变更
Jdk9以前:
- 存储在char[ ]中数组,每个字符使用两个字节(16位)。编码为UTF-16。
Jdk9:
- 存储编码为ISO-8859-1/Latin-1(每个字符一个字节, byte[] 加上编码标记来存储 )。
- 或UTF-16(每 个字符两个字节),具体取决于内容字符串的。编码标志将指示使用哪种编码。
StringBuffer 和 StringBuilder也发生改变。
8、集合特性of()
要创建一个只读、不可改变的集合,必须构造和分配它,然后添加元素,最后包装成一个不可修改的集合。
JAVA 9的方法:
public class demo04 {public static void main(String[] args) {//jdk9只读集合方法List<String> list1=List.of("1","2","3");//list1.add("aaa");不支持System.out.println(list1);Map<String,String> map=Map.of("a","aa","b","bb");System.out.println(map);}
}
9 、 InputStream增强
jdk8读写数据需要边读边写,jdk9使用TransferTo直接读写进去。
10、增强的的Stream API
- Java 9 中,Stream 接口中添加了 4 个新的方法:takeWhile, dropWhile, ofNullable, iterate 方法的重载方法,可以提供一个 Predicate (判断条件)来指定什么时候结束迭代。
- 可以通过 Optional 的新方法 stream() 将一个 Optional 对象转换为一个(可能是空的) Stream 对象。
public class demo05 {public static void main(String[] args) {/** takeWhile() 的使用* 用于从 Stream 中获取一部分数据,接收一个 判断条件 来进行选择。* 在有序的Stream 中,takeWhile 返回**从开头开始的尽量多的元素。* t ->t<40 遇到第一个不小于40 的元素就停止输出* */List<Integer> list= Arrays.asList(10,20,30,40,30,20,10);list.stream().takeWhile(t ->t<40).forEach(System.out::println);List<Integer> list2 = Arrays.asList(1,2,3,4,5,6,7);list2.stream().takeWhile(t->t<7).forEach(System.out::println);System.out.println("---------------------");/** dropWhile() 的 使用* dropWhile 的行为与 takeWhile 相反,返回剩余的元素* t ->t<40 遇到第一个大于40 的元素就开始输出* */list.stream().dropWhile(t ->t<30).forEach(System.out::println);System.out.println("---------------------");/** ofNullable() 的 使用*Java 8 中 Stream 不能完全为null,否则会报空指针异常。*Java 9 中的 ofNullable 方法允许我们创建一个单元素 Stream,* 可以包含一个非空元素,也可以创建一个空Stream。* *///java 8Stream<String> streams = Stream.of("AA","BB",null);//允许通过//Stream<Object> stream2 = Stream.of(null);//不允许通过//java 9Stream<Object> stream3 = Stream.ofNullable(null);//允许通过System.out.println("---------------------");/** iterate() 重载的使用* 可以让你提供一个 Predicate (判断条件)来指定什么时候结束迭代。* *///原始方式Stream.iterate(1,i->i+1).limit(5).forEach(System.out::println);//增强方式Stream.iterate(1,i->i<6,i->i+1).forEach(System.out::println);}
}
11、Optional 类中stream()使用
public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("张三");list.add("李四");list.add("王五");list.add("赵六");Optional<List<String>> optional =Optional.ofNullable(list);//optional中只用一个元素 [张三, 李四, 王五, 赵六]optional.stream().limit(2).forEach(System.out::println);//flatMap(x->x.stream())将一个元素 [张三, 李四, 王五, 赵六],再变为一个一个的元素optional.stream().flatMap(x->x.stream()).limit(2).forEach(System.out::println);list.stream().limit(2).forEach(System.out::println);}
}
第二章 JDK10 新特性
1、局部变量类型推断
在局部变量中使用时,这些情况不适用:初始值为null,方法引用,数组静态初始化,Lambda表达式。
public class demo01 {public static void main(String[] args) {//1.局部变量的初始化var list = new ArrayList<>();list.add(1);list.add(2);list.add(3);//2.增强for循环中的索引for (var v : list) {System.out.println(v);}// 3.传统for循环中for (var i = 0; i <3 ; i++) {System.out.println(i);}/** 在局部变量中使用时,如下情况不适用:* *///初始值为nullvar a=null;//方法引用var b=System.out::println;//Lambda表达式var c=()->Math.random();//数组静态初始化var arr={"1","2","2"}//数组动态初始化可以var arr2=new int[]{1,2,3};}
}
注意: var 不是一个关键字,不需要担心变量名或方法名会与 var发生冲突。
2、 新增不可变集合方法
jdk9 添加了 of ,jdk10新增copyOf方法,它们两个都用来创建不可变的集合。
不同之处:
public static void main(String[] args) throws Exception {//若初始的list1为不可变集合,copyOf之后的List2==list1var list1 = List.of("AA","BB","CC");var list2 = List.copyOf(list1);System.out.println(list1==list2);//true//若初始的list3为普通集合,copyOf之后的List2!=list1var list3 = new ArrayList<String>();list3.add("AA");list3.add("BB");List<String> list4 = List.copyOf(list3);System.out.println(list3==list4); //false
}
copyOf 方 法 会 先 判 断 来 源 集 合 是 不 是AbstractImmutableList 类型的。如果是,就直接返回;如果不是,则调用 of()方法 创建一个新的集合。
第三章 JDK 11新特性
1 、增加ZGC垃圾回收器
ZGC, A Scalable Low-Latency Garbage Collector(Experimental)ZGC, 这应该是JDK11最为瞩目的特性, 没有之一。 但是后面带了Experimental,说明这还不建议用到生产环境。
ZGC是一个并发, 基于region, 压缩型的垃圾收集器, 只有root扫描阶段会STW(stop the world), 因此GC停顿时间不会随着堆的增长和存活对象的增长而变长。
没有用到生产环境。
2、 Optional加强
以很方便的将一个 Optional 转换成一个 Stream, 或者当一个空 Optional 时给它一个替代。
3、新增HTTP客户端API
-
这是 Java 9 开始引入的一个处理 HTTP 请求的的 HTTP Client API,支持同步和异步,在 Java 11 中为正式可用状态,在java.net 包中。
-
它将替代仅适用于blocking模式的HttpURLConnection(HttpURLConnection是在HTTP 1.0的时代创建的,并使用了协议无关的方法),并提供对WebSocket 和 HTTP/2的支持。
public static void main(String[] args) throws Exception {HttpClient client = HttpClient.newHttpClient();HttpRequest request =HttpRequest.newBuilder(URI.create("http://www.baidu.com")).build();HttpResponse.BodyHandler<String> responseBodyHandler = HttpResponse.BodyHandlers.ofString();HttpResponse<String> response = client.send(request, responseBodyHandler);String body = response.body();System.out.println(body);
}
第四章 JDK 14 新特性
改进的NullPointerExceptions,jdk14以前空指针异常,会指出异常所在处。
jdk14之前空指针异常:
jdk14以后的空指针异常:
第五章 jdk15特性
jdk15提供text block (文本块)功能,解决字符串多行换行问题:
public static void main(String[] args) {//jdk15增加文本块String str = """helloworldhahaha""";System.out.println(str);
}
第六章 JDK 16 新特性
解决switch语句的一些不规则性成为障碍:
比如case标签之间的默认控制行为
case块中的默认范围
无意义的break语句。
但底层还是原始的switch的代码。
public class demo01 {public static void main(String[] args) {int level = new Random().nextInt(4);String str = null;switch (level){case 1-> str="优秀";case 2 -> str="good";case 3-> str="yiban";}System.out.println(str);String str2 = switch (level){//必须有defaultcase 1 -> "haohao";case 2-> "good";default -> "yiban";};System.out.println(str2);int level2 = new Random().nextInt(12);String jiJi = null;switch (level2){case 3,4,5 -> jiJi="chun";case 6,7,8->jiJi="xia";case 9,10,11->jiJi="qiu";default -> jiJi="dong";}System.out.println(jiJi);String strLeave=switch (level){//必须有defaultcase 0,1,2->{System.out.println("hhh");yield "haohaohaoa";}default -> "jjjjj";};System.out.println(strLeave);}}