Java8-17新特征总结

由于在CSDN上部分图片显示不出,建议去语雀平台进行查看
链接:https://www.yuque.com/docs/share/2f3f5707-35ed-430a-bf1e-5e2dbf8127b0?# 《Java8-17新特性》
另外,本人将持续更新相关java相关知识,如果感兴趣的小伙伴可以在我的语雀知识库进行收藏。
知识库链接:https://www.yuque.com/books/share/ffbf2b86-52af-4a4f-b144-507a890fb8dc?# 《Teng的计算机知识库》

  1. Java8新特征
    1.1 Lambda表达式
    这个应该在熟悉不过了,这里只讲下语法就行了。😊😊
    语法格式:
    1.2 函数式接口
    只包含一个抽象方法的接口,称为 函数式接口。
    我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。
    在java.util.function包下定义了Java 8 的丰富的函数式接口
    Java内置四大核心函数式接口
    返回类型参数类型函数式接口用途对类型为T的对象应用操作,包含方法:CONSUMERTVOID消费型接口VOID ACCEPT(T T)SUPPLIERT无返回类型为T的对象,包含方法:TGET()供给型接口FUNCTION<T, R>对类型为T的对象应用操作,并返回结果.结R果是R类型的对象.包含方法:RAP函数型接口APPLY(T T)PREDICATE并返回确定类型为T的对象是否满足某约束,并TBOOLEAN断定型接口BOOLEAN 值.包含方法:BOOLEAN TEST(T T)
    image.png

其他接口
参数类型返回类型函数式接口用途类型的结对类型为T,U参数应用操作,返回RBIFUNCTION<T,U, R>T,UR果.包含方法为:RAPPLY(TT,UU);对类型为T的对象进行一元运算,并返回T类型的UNARYOPERATORTT结果.包含方法为:TAPPLY(T T);(FUNCTION子接口)对类型为T的对象进行二元运算,并返回T类型的BINARYOPERATORT,TT结果.包含方法为: TAPPLY(TT1,TT2);(BIFUNCTION子接口)对类型为T,U参数应用操作.BICONSUMER<TT,U>T,UVOID包含方法为:VOID ACCEPT(TT,UU)BOOLEAN TEST(T T,U U)BIPREDICATE<T,U>包含方法为:T,UBOOLEANTOLNTFUNCTIONINT分别计算INT,LONG,DOUBLE值的函数TOLONGFUNCTIONLONGTODOUBLEFUNCTIONDOUBLEINTINTFUNCTION参数分别为INT,LONG,DOUBLE类型的函数RLONGFUNCTIONLONGDOUBLEFUNCTIONDOUBLE
image.png

编码实现
1.3 方法引用与构造器引用
方法引用可以看做是Lambda表达式深层次的表达。换句话说,方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法,可以认为是Lambda表达式的一个语法糖。
要求
实现接口的抽象方法的参数列表和返回值类型,必须与方法引用的方法的参数列表和返回值类型保持一致!
用法

对象:: 实例方法名

类:: 静态方法名

类::示例方法名
构造器引用
可以把构造器引用赋值给定义的方法,要求构造器参数列表要与接口中抽象方法的参数列表一致!且方法的返回值即为构造器对应类的对象。
1.4 StremaAPI
概述:Stream是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,Stream 讲的是计算!”
注意:
1
Stream 自己不会存储元素。
2
Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
3
Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行
操作Stream的步骤
1
创建 Stream
一个数据源(如:集合、数组),获取一个流。
2
中间操作
一个中间操作链,对数据源的数据进行处理。
3
终止操作( 终端操作)
一旦执行终止操作,就执行中间操作链,并产生结果。之后,不会再被使用。
终上操作FILTER数据源MAP一系列"中间操作"形成的流水线
image.png

创建Stream流的方式
1
通过集合

default Stream stream() : 返回一个顺序流

default Stream parallelStream() : 返回一个并行流(不要随意乱用哦)
这里简单介绍下并行流:并行流 就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
2
通过数组

Arrays 的静态方法 stream()。 static Stream stream(T[] array): 返回一个流
3
通过Stream 的of()

Stream类静态方法 of(), 通过显示值创建一个流。它可以接收任意数量的参数。 public static Stream of(T… values) : 返回一个流
4
创建无限流

使用静态方法 Stream.iterate() 和 Stream.generate(),创建无限流。

迭代。public static Stream iterate(final T seed, final UnaryOperator f)

生成。public static Stream generate(Supplier s)
Stream的中间操作
多个 中间操作可以连接起来形成一个 流水线,除非流水线上触发终止操作,否则 中间操作不会执行任何的处理!而在 终止操作时一次性全部处理,称为“惰性求值"。
1
筛选和切片
描述方法FILTER(PREDICATE P)接收LAMBDA,从流中排除某些元素DISTINCT()筛选,通过流所生成元素的HASHCODE()和EQUALS()去除重复元素LIMIT(LONG MAXSIZE)截断流,使其元素不超过给定数量跳过元素,返回一个扔掉了前N个元素的流.若流中元素不足N个,则返回一SKIP(LONG N)个空流.与LIMIT(N)互补
image.png

2
映射
描述方法接收一个函数作为参数,该函数会被应用到每个元MAP(FUNCTION F)素上,并将其映射成一个新的元素.接收一个函数作为参数,该函数会被应用到每个元MAPTODOUBLE(TODOUBLEFUNCTION F)素上,产生一个新的DOUBLESTREAM.接收一个函数作为参数,该函数会被应用到每个元MAPTOLNT(TOLNTFUNCTION F)素上,产生一个新的INTSTREAM.接收一个函数作为参数,该函数会被应用到每个元MAPTOLONG(TOLONGFUNCTION F)素上,产生一个新的LONGSTREAM.接收一个函数作为参数,将流中的每个值都换成另FLATMAP(FUNCTION F)一个流,然后把所有流连接成一个流
image.png

3
排序
描述方法产生一个新流,其中按自然顺序排序SORTED()产生一个新流,其中按比较器顺序排序SORTED(COMPARATOR COM)
image.png

Stream的终止操作

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值,例如:List、Integer,甚至是 void 。

流进行了终止操作后,不能再次使用。
1
匹配和查找
描述方法ALLMATCH(PREDICATE P)检查是否匹配所有元素检查是否至少匹配一个元素ANYMATCH(PREDICATE P)检查是否没有匹配所有元素NONEMATCH(PREDICATEP)FINDFIRST()返回第一个元素返回当前流中的任意元素FINDANY()
image.png

描述方法返回流中元素总数COUNT()返回流中最大值MAX(COMPARATOR C)返回流中最小值MIN(COMPARATOR C)内部迭代(使用COLLECTION接口需要用户去做迭代,称为外部迭代.STREAMAPI使用内部迭FOREACH(CONSUMER C)相反,代–它帮你把迭代做了)
image.png

2
归约
描述方法可以将流中元素反复结合起来,得到一REDUCE(T IDEN, BINARYOPERATOR B)个值.返回T可以将流中元素反复结合起来,得到一REDUCE(BINARYOPERATOR B)个值.返回OPTIONAL备注:MAP和REDUCE的CE模式,因GOOGLE的连接通常称为MAP-REDUCE用它来进行网络搜索而出名.
image.png

3
收集
方法描述将流转换为其他形式.接收一个COLLCOLLECTOR接口的实现,用于给STREAM中元素做汇总COLLECT(COLLECTOR C)的方法COLLECTOR接口中方法的实现决定了如何对流执行收集的操作(如收集到LIST,MAP).另外,COLLECTORS实用类提供了很多静态方法,可以方便地创建常见收集器实例,具体方法与实例如下表:
image.png

作用方法返回类型把流中元素收集到LISTLISTTOLISTLIST EMPS LIST.STREAM().N().COLLECT(COLLECTORS.TOLIST();把流中元素收集到SETSETTOSETSET EMPS-LIST.STREAM().COLLECT(COLLECTORS.TOSET();把流中元素收集到创建的集合COLLECTIONTOCOLLECTIONCOLLECTION EMPS -LIST.STREAM().COLLECT(COLLECTORS.TOCOLLECTION(ARRAYLIST:;NEW);计算流中元素的个数COUNTINGLONGLONG COUNT LIST.STREAM().COLLECT(COLLECTORS.COUNTING();对流中元素的整数属性求和INTEGERSUMMINGLNTINT TOTAL-LIST.STREAM().COLLECT(COLLECTORS.SUMMINGINT(EMPLOYEE::GETSALARY);计算流中元素LNTEGER属性的平均值DOUBLEAVERAGINGLNTDOUBLE AVG - LIST.STREAM().COLLECT(COLLECTORS.AVERAGINGINT(EMPLOYEE:::GETSALARY);收集流中INTEGER属性的统计值.如:平SUMMARIZINGLNTINTSUMMARYSTATISTICS均值INT SUMMARYSTATISTICSISS- LIST STREAM().COLLECT(COLLECTORS.SUMMARIZINGINT(EMPLOYEE::GETSALARY);
image.png

连接流中每个字符串JOININGSTRINGSTRING STR- LIST.STREAM(),MAP(EMPLOYEE::GETNAME).COLLECT(COLLECTORS.JOINININING(EMPLOYEE::GETNAME).CO根据比较器选择最大值OPTIONALMAXBYOPTIONALMAX- IST.STREAM(,COLLECT(COLLECTORS.MAXBY(COMPLOYEE;IGETSALARY);OPTIONAL根据比较器选择最小值MINBYOPTIONAL MIN - LIST.STREAM().COLLECT(COLLECTORS.MINBY(COMPARINGINT(EMPLOYEE:IGETSALARY));从一个作为累加器的初始值开始,归约产生的类型REDUCING利用BINARYOPERATOR与流中元素逐个结合,从而归约成单个值INT TOTAL-LIST:STREAM().COLLECT(COLLECTORS REDUCING(O,EMPLOYEE::GETSALAR, INTEGER::SUM));包裹另一个收集器,对其结果转COLLECTINGANDTHEN转换函数返回的类型换函数- LIST.STREAM().COLLECT(COLLECTORS.COLLECTINGANDTHEN(COLLECTORS.TOLIST), LISTIST:SIZE);INTHOWLIST.根据某属性值对流分组,属性为K,MAP<K,LIST>GROUPINGBY结果为VMAP<EMP.STATUS, LIST> MAP: LIST.STREAM()COLLECT(COLLECTORS.GROUPINGBY(EMPLOYEE::GETSTATUS));根据TRUE或FALSE进行分区MAP<BOOLEAN,LIST>PARTITIONINGBYMAP<BOOLEAN,LIST> VD - IIST,STREAM(,COLLECT(COLLECT(COLLECTORS.PARTIONINGBY(EMPLOYEE;IGETMANAGE)
image.png

1.5 Optional类
Optional 类(java.util.Optional) 是一个容器类,它可以保存类型T的值,代表这个值存在。或者仅仅保存null,表示这个值不存在。原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常。
一些方法
OPTIONAL提供很多有用的方法,这样我们就不用显式进行空值检测.创建OPTIONAL类对象的方法:OPTIONAL.OF(T):创建一个OPTIONAL 实例,T必须非空:OPTIONAL.EMPTY():创建一个空的OPTIONAL 实例OPTIONAL.OFNULLABLE(T T):T可以为NULL判断OPTIONAL容器中是否包含对象:BOOLEAN ISPRESENT():判断是否包含对象CONSUMER):如果有值,就执行CONSUMERVOID IFPRESENT(CONSUMER<? SUPER THE接口的实现代码,并且该值会作为参数传给它.获取OPTIONAL容器的对象:TGET):如果调用对象包含值,返回该值,否则抛异常TORELSE(TOTHER):如果有值则将其返回,否则返回指定的OTHER对象.TOREISEGET(SUPPLIER<?EXTENDS T>OTHER):如果有值则将其运回,否则这回由SUPPLIER接口实现提供的对象.T ORELSETHROW(SUPPLIER<?EXTENDS X>EXCEPTIONSUPPLIER):如果有值则将其返否则抛出由SUPPLIER接口实现提供的异常.
image.png

1.6 新时间日期API
LocalDate、LocalTime、LocalDateTime 类的实例是不可变的对象,分别表示使用 ISO-8601日历系统的日期、时间、日期和时间。它们提供了简单的日期或时间,并不包含当前的时间信息。也不包含与时区相关的信息。
常用方法
方法示例描述静态方法,根据当前时间创建对象LOCALDATE LOCALDATE LOCALDATE.NOW();NOW()LOCALTIMELOCALTIME LOCALTIME.NOW();LOCALDATETIMENOW();LOCALDATETIME LOCALDATETIME :LO静态方法,根据指定日期/时间创建OF()LOCALDATE LOCALDATE LOCALDATE.OF(2016,10,26);LOCALTIME LOCALTIME.LOCALTIME.OF(02,22,56);对象LOCALDATETIME LOCALDATETIME - LOCALDATETIME.OF(2016,10,26,12,10,55);向当前LOCALDATE对象添加几天PLUSDAYS,PLUSWEEKS,几周,几个月,几年PLUSMONTHS,PLUSYEARS从当前LOCALDATE对象减去几天,MINUSDAYS,MINUSWEEKS,几周,几个月,几年MINUSMONTHS,MINUSYEARS添加或减少一个DURATION 或 PERIODPLUS,MINUS将月份天数,年份天数,月份,年WITHDAYOFMONTH,份修改为指定的值并返回新的WITHDAYOFYEAR,LOCALDATE对象WITH MONTH,WITHYEAR获得月份天数(1-31)GETDAYOFMONTH获得年份天数(1-366)GETDAYOFYEAR获得星期几(返回一个DAYOFWEEKGETDAYOFWEEK枚举值)获得月份,返回一个MONTH枚举值GETMONTH获得月份(1-12)GETMONTHVALUE获得年份GETYEAR获得两个日期之间的 PERIOD 对象,UNTIL或者指定CHRONOUNITS的数字比较两个LOCALDATEISBEFORE,ISAFTER判断是否是闰年ISLEAP YEAR
image.png

时间戳Instant — 用于“时间戳”的运算。它是以Unix元年(传统的设定为UTC时区1970年1月1日午夜时分)始所经历的描述进行运算。
Duration 和 Period— Duration:用于计算两个“时间”间隔; Period:用于计算两个“日期”间隔
日期解析与格式化
java.time.format.DateTimeFormatter类:该类提供了三种格式化方法:

预定义的标准格式

语言环境相关的格式

自定义的格式
时区的处理
java8 中加入了对时区的支持,带时区的时间为分别为:ZonedDate、ZonedTime、ZonedDateTime
其中每个时区都对应着ID,地区ID都为“{区域}/{城市}”的格式。
例如 :Asia/Shanghai 等。
ZoneId:该类中包含了所有的时区信息。
getAvailableZoneIds() : 可以获取所有时区时区信息。
of(id) : 用指定的时区信息获取ZoneId对象。
1.7 接口中的默认方法与静态方法
这个在javaSE中已经说过,这里不再描述了。😊😊
2. Java9新特征
Java 9 在2017年9月21日发布。
java 9 提供了超过150项新功能特性,包括备受期待的模块化系统、可交互的 REPL 工具:jshell,JDK 编译工具,Java 公共 API 和私有代码,以及安全增强、扩展提升、性能管理改善等。可以说Java 9是一个庞大的系统工程,完全做了一个整体改变。
2.1 JDK 和 JRE 目录结构的改变
哈哈,说起这个还要从我把java8升级到java17说。当我进行配置jdk17时,发现与jdk8不太一样,于是我查询资料发现在jdk9时,jdk与jre的目录结构已经改变。不过这个就作为小知识,了解一下就行啦。
JDK HOMEJREBININCLUDELIBJDK8的目录结构LIBBIN包含命令行开发和调试工具,如JAVAC,JAR和JAVADOC.BIN目录包含在编译本地代码时使用的C/C+头文件INCLUDE目录包含JDK工具的几个JAR和其他类型的文件.它有一个TOOLS.JAR文件,其中包LIB目录含JAVAC编译器的JAVA类包含基本命令,如JAVA命令.在WINDOWS平台上,它包含系统的运行时动态链.JRE/BIN目录接库(DLL).包含用户可编辑的配置文件,如.PROPERTIES和.POLICY文件.包含几个JAR.JRE/LIB目录的技,RT.JAR文件包含运行时的JAVA类和资源文件.
image.png

北电脑 > DATA(D:)> JAVA CONFIG > JAVA > JDK1.8.0 311 ,在JDK1.8.0311中搜素修改日期大小类型名称文件夹2022/5/41:30BIN文件夹INCLUDE2022/5/41:30文件夹2022/5/41:30JRE文件夹2022/5/41:30LEGAL文件夹2022/5/41:30LIB文件COPYRIGHT2021/9/27 5:454 KB压缩(ZIPPED)文件夹5,114 KB2022/5/41:30JAVATX-SRC.ZIP文本文档2022/5/41:301 KBIMC.TXT文件1 KB2022/5/41:30LICENSECHROME HTML DOC…1 KBREADME.HTML2022/5/41:30文件1 KB2022/5/41:30RELEASE(压缩(ZIPED)文件夹20,669 KB2021/9/27 5:45SRC.ZIP文本文档1 KB2022/5/41:30THIRDPARTYLICENSEREADME.TXT文本文档THIRDPARTYLICENSEREADME-JAVAFX.TXT1 KB2022/5/41:30
image.png

JDK HOMEJDK9的目录结构LEGALJMODSBINLIBINCLUDECONF没有名为JRE的子目录包含所有命令.在WINDOWS平台上,它继续包含系统的运行时动态链接库.BIN目录包含用户可编辑的配置文件,例如以前位于JREVIB目录中的.PROPERTIES和.POLICY文件CONF目录包含要在以前编译本地代码时使用的C/C++头文件.它只存在于JDK中目录INCLUDEL包含JMOD格式的平台模块.创建自定义运行时映像时需要它.它只存在于JDK中JMODS目录包含法律声明目录LEGAL包含非WINDOWS平台上的动态链接本地库.其子目录和文件不应由开发人员直接编辑或使用LIB目录
image.png

此电脑 >DATA(D:)>JAVA CONFIG > JAVA >JDK-17.04在JDK-17.0.4中修改日期类型名称大小文件夹2022/7/30 17BIN文件夹2022/7/3019:17CONF文件夹2022/7/3019:17INCLUDE文件夹2022/7/3019:17IMODS文件夹2022/7/3019:17LEGAL文件夹2022/7/3019:17LIB文件LICENSE7KB2022/7/3019:17文件1 KB2022/7/3019:17README文件2KB2022/7/3019:17RELEASE
image.png

2.2 模块化系统
这个功能可以用来管理各个模块中哪些包可以被外来访问使用,哪些不可以,多了解以下也是不错的。
本质上讲也就是说,用模块来管理各个package,通过声明某个package暴露,,模块(module)的概念,其实就是package外再裹一层,不声明默认就是隐藏。因此,模块化使得代码组织上更安全,因为它可以指定哪些部分可以暴露,哪些部分隐藏。
从java9开始模块化系统由Jigsaw->Modularity
模块将由通常的类和新的模块声明文件(module-info.java)组成。该文件是位于java代码结构的顶层,该模块描述符明确地定义了我们的模块需要什么依赖关系,以及哪些模块被外部使用。在exports子句中未提及的所有包默认情况下将封装在模块中,不能在外部使用。
DEMO1MMVMMSRCMAINJAVACCOM.IT JAVA9TESTWAWWWWWWWWWWMODULETESTMODULE-INFO.JAVARESOURCESTEST.GITIGNOREM POM.XMLDEMO2SRCMAINJAVACOM.LT.DEMO2.BEANC PERSONMODULE-INFOJAVARESOURCES三TEST.GITIGNORE
image.png
CNEWJAVA CLASSOJECTMODULE-INFO.JAVKOTLIN CLASS/FILEXCUTCTRL+XALGORITHMD:\MYCFILE面CTRL+CCOPY.IDEASCRATCH FILECTRL+ALT+SHIFT+LNSERTCOPY PATH/REFERENCE…DEMO1PACKAGECTRL+VPASTESRCPACKAGE-INFOJAVAMAINFIND USAGESALT+F7MODULE-INFO,JAVAJAVAFIND IN FILES…CTRL+SHIFT+FHTML FILEREPLACE IN FILES…CTRL+SHIFT+RKOTLIN SCRIPT (BETA)ANALYZEKOTLIN WORKSHEET(BETA)MOREFACTORRESOURSTYLESHEETTESTJAVASCRIPT FILEJSBOOKMARKSGITIGNORETYPESCRIPT FILEREFORMAT CODECTRL+ALT+LNACKAAO ICON EILO
image.png

想要在demo1模块中使用demo2模块下包结构的文件,需要在demo2模块的module-info.java中声明:
*/MODULE DEMO2 EXPORTS COM.LT.DEMO2.BEAN;
image.png

exports :控制着哪些包可以被其它模块访问到 。 所有不被导出的包默认都被封装在模块里面 。
对应在demo1模块中的module-info.java中声明:
*/MODULE DEMO1 REQUIRES DEMO2;
image.png

requires :指明对其它模块的依赖。
这样就完成了对模块的管理。
2.3 try语句的语法改进
Java 8 中,可以实现资源的自动关闭,但是要求执行后必须关闭的所有资源必须在try子句中初始化,否则编译不通过。如下例所示:
Java 9 中,用资源语句编写try将更容易,我们可以在try子句中使用已经初始化过的资源,此时的资源是final的。
2.4 快速创建只读集合
调用集合中静态方法of(),可以将不同数量的参数传输到此工厂方法中。此功能可用于Set和List,也可用于Map的类似形式。此时得到的集合,是不可变的:在创建后,继续添加元素到这些集合会导致 “UnsupportedOperationException” 。
2.5 InputStream的加强
InputStream 终于有了一个非常有用的方法:transferTo,可以用来将数据直接传输到 OutputStream,这是在处理原始数据流时非常常见的一种用法,如下示例。个人认为这个方法挺不错!!!
关于java9的新特征就讲到这里,其实还有许多java9的新特征,如接口中的私有方法,钻石操作符使用升级,JShell命令,String存储结构的改变等等,这里不再过多进行讲述。
3. Java10新特征
2018年3月21日,Oracle官方宣布Java10正式发布。
需要注意的是 Java 9 和 Java 10 都不是 LTS (Long-Term-Support) 版本。和过去的 Java 大版本升级不同,这两个只有半年左右的开发和维护期。而未来的 Java 11,也就是 18.9 LTS,才是 Java 8 之后第一个 LTS 版本。
JDK10一共定义了109个新特性,其中包含12个JEP(对于程序员来讲,真正的新特性其实就一个),还有一些新API和JVM规范以及JAVA语言规范上的改动。
3.1 局部变量类型推断
产生背景:
开发者经常抱怨Java中引用代码的程度。局部变量的显示类型声明,常常被认为是不必须的,给一个好听的名字经常可以很清楚的表达出下面应该怎样继续。
好处:减少了啰嗦和形式的代码,避免了信息冗余,而且对齐了变量名,更容易阅读!
适用于以下情况
不适用于:

没有初始化的局部变量声明

方法的返回类型

方法的参数类型

构造器的参数类型

属性

catch块
对于java9的新特征,我们就讲解这一个,其余对于我们程序员来说都不太重要!!!😊😊
4. Java11新特征
北京时间 2018年9 月 26 日,Oracle 官方宣布 Java 11 正式发布。这是 Java 大版本周期变化后的第一个长期支持版本,非常值得关注。JDK 11 是一个长期支持版本 (LTS, Long-Term-Support )
JDK11 引入了两种新的 GC,其中包括也许是划时代意义的 ZGC,虽然其目前还是实验特性,但是从能力上看,这是 JDK 的一个巨大突破,为特定生产环境的苛刻需求提供了一个可能的选择。例如,对部分企业核心存储等产品,如果能够保证不超过 10ms 的 GC 暂停,可靠性会上一个大的台阶,这是过去我们进行 GC 调优几乎做不到的,是能与不能的问题。
4.1 新增的字符串方法
举例描述"".ISBLANK();//TRUE判断字符串是否为空白JAVASTACK ".STRIP(); // "JAVASTACK"去除首尾空白去除尾部空格JAVASTACK"JAVASTACK ".STRIPTRAILING(); // "JAVASTACK ".STRIPLEADING(); // “JAVASTACK去除首部空格"JAVA”.REPEAT(3);// “JAVAJAVAJAVA"复制字符串行数统计"A\NB\NC”.LINES().COUNT();//3
image.png

4.2 Optional类加强
Optional 也增加了几个非常酷的方法,现在可以很方便的将一个 Optional 转换成一个 Stream, 或者当一个空 Optional 时给它一个替代的。
描述新增方法新增的版本判断VALUE是否为空JDK 11BOOLEAN ISEMPTY()IFPRESENTORELSE(CONSUMER<?VALUE非空,执行参数1功能;如果VALUEJDK9为空,执行参数2功能SUPER T>ACTION ,RUNNABLE EMPTYACTION)OPTIONALOR(SUPPLIER<?JDK9VALUE非空,返回对应的OPTIONAL;VALUE为空,返回形参封装的OPTIONALEXTENDS OPTIONAL<? EXTENDS T>> SUPPLIER)VALUE非空,返回仅包含此VALUE的JDK9STREAMSTREAM()STREAM;否则,返回一个空的STREAMVALUE非空,返回VALUE;否则抛异常T ORELSETHROW()JDK 10NOSUCHELEMENTEXCEPTION
image.png

4.3 更 简化的编译运行程序
看下面的代码。
// 编译
javac Javastack.java
// 运行
java Javastack
在我们的认知里面,要运行一个 Java 源代码必须先编译,再运行,两步执行动作。而在未来的 Java 11 版本中,通过一个 java 命令就直接搞定了,如以下所示:
java Javastack.java
一个命令编译运行源代码的注意点:

执行源文件中的第一个类, 第一个类必须包含主方法。

并且不可以使用其它源文件中的自定义类, 本文件中的自定义类是可以使用的
关于java11的新特性暂时讲这么多,由于其他新特性我们此阶段暂时用不到,例如:全新的HTTP客户端API,ZGC,GrralJVM等等,故不再讲解。
5. Java12-16新特征
5.1 全新的switch语法
以前的switch写法
改进后的switch语法
注意:switch表达式在Java 14才正式开放使用,所以我们项目的代码级别需要调整到14以上才可使用。
5.2 文本块
这个语法类似python中的三引号,没错,在java13中也引入了相关的语法。
注意:文本块表达式在Java 15才正式开放使用,所以我们项目的代码级别需要调整到15以上才可使用。
5.3 新的instanceof语法
在Java 14,instanceof迎来了一波小更新。
当我们进行类型转换时,首先需要先进行判断,然后进行转换,如下所示
但引入语法后,使用如下
注意:新的instanceof语法在Java 16才正式开放使用,所以我们项目的代码级别需要调整到16以上。
5.4 记录(Record)类型
继类、接口、枚举、注解之后的又一新类型来了,它的名字叫"记录",在Java 14中首次出场。
记录类型本质上也是一个普通的类,不过是final类型且继承自java.lang.Record抽象类的,它会在编译时,会自动编译出 public get hashcode 、equals、toString 等方法。这个记录类型非常类似与Lombok
使用起来也是非常方便,自动生成了构造方法和成员字段的公共get方法、toString()、equals()等方法
但是提供的构造方法中,有了有参就无空参构造,即不会全部提供。
注意:记录类型在Java 16才正式开放使用,所以我们项目的代码级别需要调整到16以上。
5.5 空指针异常的小改进
在java中遇到最终的异常恐怕就是NPE了吧,就比如如下例子:
那么为空时,就会直接
EXCEPTION IN THREAD “MAIN” JAVA.LANG.NULLPOINTEREXCEPTION CREATE BREAKPOINTAT COM.TEST.MAIN.MAIN(MAIN.JAVA:10)
image.png

但是由于我们这里a和b都调用了length()方法,虽然空指针异常告诉我们问题出现在这一行,但是到底是str1为null还是str2为null呢?我们是没办法直接得到的,就很难受😫😫
但是当我们在Java 14或更高版本运行时:
CANNOT INVOKE “STRING.LENGTH()”"STR2"EXCEPTION IN THREADJAVA.LANG.NULNULLNULLPOINTEREXCEPTION CREATE BREAKPAKPOINTBECAUSEIS’MAINM.DS01.LIANBIAO.MAIN.TEST1(MAIN.JAVA:29)AT COM.LT.ALGORITHM.DSAT COM.1T.ALGORITHM.DSO1.LIANBIAO.MAIN.MAIN(MAIN.JAVA:25)
image.png

这里会明确指出是哪一个变量调用出现了空指针,就很人性化,给他两个👍👍。
6. Java17新特征
6.1 密封类型
在Java中,我们可以通过继承(extends关键字)来实现类的能力复用、扩展与增强。但有的时候,可能并不是所有的类我们都希望能够被继承。所以,我们需要对继承关系有一些限制的控制手段,而密封类的作用就是限制类的继承。
实际上在之前我们如果不希望别人继承我们的类,可以直接添加final关键字
这样有一个缺点,如果添加了final关键字,那么无论是谁,包括我们自己也是没办法实现继承的,但是现在我们有一个需求,只允许我们自己写的类继承A,但是不允许别人写的类继承A,这时该咋写?在Java 17之前想要实现就很麻烦。
但是现在我们可以使用密封类型来实现这个功能:
Java
复制代码
1
2
3
4
5
6
7
public sealed class A permits B {
// 在class关键字前添加sealed关键字,表示此类为密封类型,permits后面跟上允许继承的类型,多个子类使用逗号隔开
}

// 继承的子类
public final class B extends A {
}
密封类型有以下要求:

可以基于普通类、抽象类、接口,也可以是继承自其他接抽象类的子类或是实现其他接口的类等。

必须有子类继承,且不能是匿名内部类或是lambda的形式。

sealed写在原来final的位置,但是不能和final、non-sealed关键字同时出现,只能选择其一.

继承的子类必须显式标记为final、sealed或是non-sealed类型
标准的声明格式如下:
Java
复制代码
1
2
3
public sealed [abstract] [class/interface] 类名 [extends 父类] [implements 接口, …] permits [子类, …]{
//里面的该咋写咋写
}
注意子类格式为:
Java
复制代码
1
2
3
4
5
public [final/sealed/non-sealed] class 子类 extends 父类 { //必须继承自父类
//final类型:任何类不能再继承当前类,到此为止,已经封死了。
//sealed类型:同父类,需要指定由哪些类继承。
//non-sealed类型:重新开放为普通类,任何类都可以继承。
}
我们可以看到其他的类无论是继承A还是继承B都无法通过编译:
PUBLIC CLASS C EXTENDS无法从FINAL’COM.TEST.B’继承更多操作…T将B’设为非FINALTVPUBLIC CLASSA1EXTENDS密封层次结构中不允许使用C将’C 添加到密封类’A 的PERMITS列表 T个T4更多操作…
image.png

但是如果此时我们主动将B设定为non-sealed类型:
这样就可以正常继承了,因为B指定了non-sealed主动放弃了密封特性,这样就显得非常灵活了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ambition0823

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值