天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。

Java 程序员不要错过这几个优秀功能!涨知识…

itzoo 347次浏览 0个评论

点击“终码一生”,关注,置顶公众号

每日技术干货,第一时间送达!



Java程序开发人员如今跟上Java频繁发布功能的节奏并不容易。如果错过了密封类、文本块、记录类、新字符串方法以及可选类,则需要修复或弥补这些功能。

Java现在基本上保持在每半年发布一个新的版本,这有利于保持Java的新鲜度和相关性,但它很容易让开发人员错过引入的功能。本文汇总了几个有用的新功能并对其进行概述。


 

1

可选类(Optional class)


空指针异常是所有错误中最经典的错误之一。虽然开发人员可能很熟悉这个问题,但它的处理过程非常冗长,需要加以防范。至少在Java 8(以及Java 10改进)引入可选类之前是这样。


本质上,可选类允许包装一个变量,然后使用包装器的方法更简洁地处理空值。


清单1有一个多样性空指针错误的示例,其中的可选类引用foo为空(null),并且在其上访问了一个方法foo.getName()。


1.没有可选类的空指针


public class MyClass {
    public static void main(String args[]) {
      InnerClass foo = null;
      System.out.println("foo = " + foo.getName());
    }
}


class InnerClass {
  String name = "";
  public String getName(){
      return this.name;
  }
}


可选类提供了多种处理此类情况的方法,具体取决于开发人员的需要。它运行一个isPresent()方法,开发人员可以使用它来进行if检查。然而这个过程可能相当冗长。但是可选类也有函数处理的方法。例如,清单2展示了如何使用ifPresent()——注意与isPresent()的一个字母差异,只有当存在数值时才运行输出代码。


2.只有当存在数值时运行代码


public class MyClass {
    public static void main(String args[]) {
      InnerClass foo = null; //new InnerClass("Test");
      Optional fooWrapper = Optional.ofNullable(foo);
      fooWrapper.ifPresent(x -> System.out.println("foo = " + x.getName()));
      //System.out.println("foo = " + fooWrapper.orElseThrow());
    }
}
class InnerClass {
  String name = "";
  public InnerClass(String name){
      this.name = name;
  }
  public String getName(){
      return this.name;
  }
}


提示:当使用可选类时,如果使用orElse()方法通过方法调用提供默认值,需要考虑如果该值是非空的话,使用orElseGet()来提供函数引用,以获得不运行调用的性能优势。



2

记录类(预览功能)


构建Java应用程序的一个常见需求是所谓的不可变DTO(数据传输对象)。DTO用于对来自数据库、文件系统和其他数据存储的数据进行建模。传统上,DTO是通过创建一个类来创建的,该类的成员通过构造函数设置,没有getter方法来访问它们。Java 14引入并改进了Java 15,新的记录关键字为此目的提供了速记。


清单3说明了引入记录类型之前的典型DTO定义和用法。


3.一种简单的不可变DTO


public class MyClass {
    public static void main(String args[]) {
      Pet myPet = new Pet("Sheba", 10);

      System.out.println(String.format("My pet %s is aged %s", myPet.getName(), myPet.getAge()));
    }
}
class Pet {
    String name;
    Integer age;
    public Pet(String name, Integer age){
        this.name = name;
        this.age = age;
    }
    public String getName(){
        return this.name;
    }
    public Integer getAge(){
        return this.age;
    }
}


可以使用记录关键字消除大部分样板文件,如清单4所示。


4.使用记录关键字


public class MyClass {
    public static void main(String args[]) {
      Pet myPet = new Pet("Sheba", 10);

      System.out.println(String.format("My pet %s is aged %s", myPet.getName(), myPet.getAge()));
    }
}

public record Pet(String name, Integer age) {}


需要注意的是,使用数据对象的客户端代码没有改变;它的行为就像一个传统定义的对象。记录关键字足够智能,可以通过简单的定义足迹推断出存在哪些字段。


记录类还定义了equals()、hashCode()和toString()的默认实现,同时还允许开发人员覆盖这些实现。开发人员还可以提供自定义构造函数。


需要注意的是,记录不能被子类化。


另外,关注公号“终码一生”,回复关键词“资料”,获取视频教程和最新的面试资料

 

3

新字符串方法


在Java 10和Java 12中,添加了几个有用的新字符串方法。除了字符串操作方法之外,还引入了两种用于简化文本文件访问的新方法。


Java 10中的新字符串方法:

  • isBlank():如果字符串为空或字符串仅包含空格(包括制表符),则返回true。注意isBlank()与isEmpty()不同,后者仅在length为0时返回true。

  • lines():将字符串拆分为字符串流,每个字符串包含一行。每行由/r或/n或/r/n定义。例如,参见清单5。

  • strip()、stripLeading()、stripTrailing():分别从开头和结尾、仅开头和仅结尾删除空格。

  • repeat(in ttimes):返回一个字符串,该字符串采用原始字符串并重复指定的次数。

  • readString():允许从文件路径直接读取字符串,如清单6所示。

  • writeString(Path path):将字符串直接写入指定路径的文件中。


Java 12中的新字符串方法:

  • indent(int level):将字符串缩进指定的数量。负值只会影响前导空格。

  • transform(Function f):将给定的lambda应用于字符串。


5. String.lines() 示例


public class MyClass {
    public static void main(String args[]) throws IOException{
      String str = "test ntest2 nrtest3 r";
      Stream lines = str.lines();
      lines.forEach(System.out::println);
    }
}

/*
outputs:
test
test2
test3
*/

清单6.String.readString(Path path)示例

Path path = Path.of("myFile.txt");
String text = Files.readString(path);
System.out.println(text);



4

Switch表达式


Java 12引入了Switch表达式,它允许在语句中内联使用Switch。换句话说,Switch表达式返回一个值。Java 12还提供了一种箭头语法,无需显式中断即可防止失败。Java 13则更进一步改进,引入了yield关键字来明确表示Switch case返回的值。Java 14采用了新的Switch表达式语法作为完整功能。


让我们看一些例子。首先,清单7有一个传统格式(Java 8)的Switch语句示例。此代码使用变量(消息)输出已知数字的名称。


7.传统Java Switch


class Main { 
  public static void main(String args[]) {
    int size = 3;
    String message = "";

switch (size){
 case 1 :
message = "one";
 case 3 :
   message = "three";
break;
 default :
message = "unknown";
break;
}

System.out.println("The number is " + message);
  }
}


现在这段代码非常冗长并且挑剔。其实里面已经有了错误,开发人员需要仔细查找丢失的内容。清单8通过使用新Switch表达式进行了简化。


8. 新的Switch表达式


class NewSwitch { 
  public static void main(String args[]) {
    int size = 3;

    System.out.println("The number is " +
      switch (size) {
        case 1 -> "one";
        case 3 -> "three";
        default -> "unknown";
      }
    );
  }
}


在清单8中,可以看到Switch表达式就在System.out.println调用中。这已经是一个很大的可读性胜利,并且消除了多余的消息变量。此外,箭头语法通过消除break语句减少了代码占用空间。(不使用箭头语法时使用yield关键字),另外,关注公号“终码一生”,回复关键词“资料”,获取视频教程和最新的面试资料



5

文本块


Java 13通过引入文本块解决了在Java中处理复杂文本字符串的长期困扰。Java 14改进了这种支持。


JSON、XML和SQL之类的东西可能会让开发人员过多地使用多个嵌套的转义层。正如规范解释的那样:“在Java中,在字符串文字中嵌入HTML、XML、SQL或JSON的片段……通常需要使用转义和连接进行大量编辑,然后才能编译包含该片段的代码。该代码段通常难以阅读且难以维护。”


在清单9中,新的文本块语法用于创建JSON片段。


9.使用文本块的JSON


class TextBlock { 
  public static void main(String args[]) {
    String json = """
      {
        "
animal" : "Quokka",
        "
link" : "https://en.wikipedia.org/wiki/Quokka"
      }
    """;

    System.out.println(json);
  }
}


在清单9中看不到转义字符。此外,还要注意三重双引号语法。


 

6

密封类


Java 15(JEP 260)引入了密封类的概念。简而言之,新的sealed关键字允许开发人员定义哪些类可以对接口进行子类化。在这种情况下,示例胜过千言万语。参见清单10。


10.密封类示例


public abstract sealed class Pet
    permits Cat, Dog, Quokka 
{...}


界面设计者在这里使用了sealed关键字来指定允许哪些类扩展Pet类。


总的来说,很明显,Java发布功能的新方法正在奏效。人们看到许多新想法通过JEP(JDK增强提案)过程转化为实际可用的Java功能。这对Java开发人员来说是一个好消息。这意味着他们正在使用一种充满活力、不断发展的语言和平台。


来源:https://developer.51cto.com/art/202110/684674.htm


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。


往期推荐



Java 程序员利器:lombok神工具

不得不说,DataGrip 太吊了!!

流弊!亿级流量电商系统 JVM 模型参数预估方案

面试官:Redis为什么默认16个数据库?

SpringBoot 如何实现定时任务,写得太好了 !

牛逼!处理 Exception 的 9 个最佳实践!



ITZOO版权所有丨如未注明 , 均为原创丨转载请注明来自IT乐园 ->Java 程序员不要错过这几个优秀功能!涨知识…
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址