跟上Java的频繁发布并不容易。如果您错过了密封类、文本块、记录、新字符串方法或可选类,让我们修复它。这对于保持Java的新鲜感和相关性非常有用,但是很容易在引入新功能时错过它们。本文汇集了几个有用的新特性,并对它们进行了概述。可选的空指针异常是所有错误中最经典的错误之一。虽然它可能很熟悉,但请注意这是一个非常冗长的问题。至少在Java8引入(和Java10改进)Optional类之前。本质上,Optional类允许您包装一个变量,然后使用包装器的方法更简洁地处理空值。清单1有一个常见的空指针错误示例,其中类引用foo为null并且foo.getName()访问方法,在它上面。清单1.没有Optional的空指针publicclassMyClass{publicstaticvoidmain(Stringargs[]){InnerClassfoo=null;System.out.println("foo="+foo.getName());}}classInnerClass{Stringname="";publicStringgetName(){returnthis.name;}}Optional提供了多种方法来根据您的需要处理此类情况。它提供了isPresent()方法,可用于if检查。然而,这最终变得非常冗长。但是Optional也有函数处理的方法。例如,清单2展示了如何使用ifPresent()(注意与isPresent()的一个字母不同)仅在存在值时运行输出代码。清单2.仅当值存在时运行代码importjava.util.Optional;publicclassMyClass{publicstaticvoidmain(Stringargs[]){//新的内部类(“测试”);可选的fooWrapper=Optional.ofNullable(foo);fooWrapper.ifPresent(x->System.out.println("foo="+x.getName()));//System.out.println("foo="+fooWrapper.orElseThrow());}}classInnerClass{Stringname="";publicInnerClass(Stringname){this.name=name;}publicStringgetName(){returnthis.name;}}Tips:使用Optional时,如果你使用orElse()方法通过方法调用提供默认值,请考虑使用orElseGet()提供函数引用,以获得在值为非空时不运行调用的性能优势。记录类(预览功能)构建Java应用程序的一个常见要求是所谓的不可变DTO(数据传输对象)。DTO用于对来自数据库、文件系统和其他数据存储的数据建模。传统上,DTO是通过创建一个类来创建的,该类的成员是通过构造函数设置的,没有getter来访问它们。Java14引入并改进了Java15,record为此提供了一个简写的new关键字。清单3说明了典型的DTO定义和在引入类型之前的用法。清单3.一个简单的不可变DTOpublicclassMyClass{publicstaticvoidmain(Stringargs[]){PetmyPet=newPet("Sheba",10);System.out.println(String.format("Mypet%sisaged%s",myPet.getName(),myPet.getAge()));}}classPet{Stringname;Integerage;publicPet(String姓名,年龄整数){this.name=姓名;这。age=age;}publicStringgetName(){returnthis.name;}publicIntegergetAge(){returnthis.age;}}record我们可以使用清单4中所示的关键字消除大部分样板文件。清单4.使用记录关键字publicclassMyClass{publicstaticvoidmain(Stringargs[]){PetmyPet=newPet("Sheba",10);System.out.println(String.format("Mypet%sisaged%s",myPet.getName(),myPet.getAge()));}}publicrecordPet(Stringname,Integerage){}注意使用数据对象的客户端代码不会改变;它的行为就像一个常规定义的对象。record关键字足够聪明,可以从简单的定义足迹中推断出哪些字段存在。该类型还为、和记录定义了equals()的默认实现,同时还允许开发人员覆盖这些实现。您还可以提供自定义构造函数。hashCode()toString()请注意,记录不能被子类化。新的String方法在Java10和Java12中,String添加了几个有用的新方法。除了字符串操作方法之外,还引入了两种新方法来简化对文本文件的访问。StringJava10中的新功能:isBlank():如果字符串为空或字符串仅包含空格(包括制表符),则返回true。注意isBlank()与isEmpty()不同,isEmpty()只在长度为0时返回true。lines():将字符串拆分为字符串流,每个字符串包含一行。行由/r或/n或/r/n定义。例如,考虑下面的清单5。strip()、stripLeading()、stripTrailing():分别从前导和尾随、仅前导和尾随中删除空格。repeat(inttimes):返回一个字符串,该字符串采用原始字符串并将其重复指定的次数。readString():允许直接从文件路径读取字符串,如清单6所示。writeString(Pathpath):将字符串直接写入指定路径的文件。StringJava12中的新功能:indent(intlevel):将字符串缩进指定的量。负值只影响前导空格。transform(Functionf):将给定的lambda应用于字符串。清单5.String.lines()示例Pathpath=Path.of("myFile.txt");字符串文本=Files.readString(路径);System.out.println(文本);switch表达式Java12引入了switch允许在语句中内联使用switch表达式。换句话说,switch表达式返回一个值。Java12还提供了一种箭头语法,可以在没有显式中断的情况下防止失败。Java13更进一步,引入了yield关键字来明确指示switchcase返回的值。Java14采用了新的switch表达式语法作为一个完整的特性。让我们看一些例子。首先,清单7有一个(非常人为的)传统(Java8)格式的switch语句示例。此代码使用变量(message)输出已知号码的名称。清单7.旧式JavaswitchclassMain{publicstaticvoidmain(Stringargs[]){intsize=3;Stringmessage="";switch(size){case1:message="one";情况3:消息=“三”;中断;default:message="unknown";break;}System.out.println("Thenumberis"+message);}}现在这段代码非常冗长和挑剔。其实这里面已经有错误了!仔细寻找丢失的中断。清单8通过使用switch表达式对此进行了简化。清单8.新的开关表达式classNewSwitch{publicstaticvoidmain(Stringargs[]){intsize=3;System.out.println("Thenumberis"+switch(size){case1->"one";case3->"three";default->"unknown";});}}在清单8中,您可以看到switch表达式直接位于System.out.println调用中。这已经是一个巨大的可读性胜利,并且消除了冗余的消息变量。此外,箭头语法通过消除break语句减少了代码占用空间。(不使用箭头语法时使用yield关键字。)文字块Java13通过引入文本块解决了Java中长期存在的处理复杂文本字符串的烦恼。Java14改进了这种支持。JSON、XML和SQL之类的多层嵌套转义会让您发疯。正如规范所解释的那样:在Java中,在字符串文字中嵌入HTML、XML、SQL或JSON片段……通常需要在包含片段的代码编译之前进行大量编辑,包括转义和连接。此代码段通常难以阅读且难以维护。看一下清单9,其中新的文本块语法用于创建JSON片段。清单9.使用文本块的JSONclassTextBlock{publicstaticvoidmain(Stringargs[]){Stringjson="""{"animal":"Quokka","link":"https://en.wikipedia.org/wiki/Quokka"}""";System.out.println(json);}}在清单9中,看不到转??义字符。请注意三重双引号语法。密封类Java15(JEP260)引入了密封类的概念。简而言之,newsealed关键字允许您定义哪些类可以子类化接口。在这种情况下,一个例子胜过一千个字。参见清单10。清单10.密封类示例publicabstractsealedclassPetpermitsCat,Dog,Quokka{...}这里界面设计者使用sealed关键字来指定允许哪些类扩展Pet类。总的来说,很明显新的Java版本正在运行。我们看到许多新想法通过JEP(JDK增强提案)过程转化为实际可用的Java功能。这对Java开发人员来说是个好消息。这意味着我们正在使用一种活生生的、不断发展的语言和平台工作。需要学习更多Java资料关注博主,免费私聊博主
