02、Records
在之前的一篇文章中,我谈到了类的不可变性,它是这样定义的:
public final class Writer { private final String name; private final int age; public Writer(String name, int age) { this.name = name; this.age = age; } public int getAge() { return age; } public String getName() { return name; }
那么,对于 Records 来说,一条 Record 就代表一个不变的状态。尽管它会提供诸如 equals()、hashCode()、toString()、构造方法,以及字段的 getter,但它无意替代可变对象的类(没有 setter),以及 Lombok 提供的功能。
来用 Records 替代一下上面这个 Writer 类:
public record Writer(String name, int age) { }
1
你看,一行代码就搞定。关键是比之前的代码功能更丰富,来看一下反编译后的字节码:
public final class Writer extends java.lang.Record { private final java.lang.String name; private final int age; public Writer(java.lang.String name, int age) { /* compiled code */ } public java.lang.String toString() { /* compiled code */ } public final int hashCode() { /* compiled code */ } public final boolean equals(java.lang.Object o) { /* compiled code */ } public java.lang.String name() { /* compiled code */ } public int age() { /* compiled code */ } }
类是 final 的,字段是 private final 的,构造方法有两个参数,toString()、hashCode()、equals() 方法也有了,getter 方法也有了,只不过没有 get 前缀。但是没有 setter 方法,也就是说 Records 确实针对的是不可变对象——鉴定完毕。那怎么使用 Records 呢?
public class WriterDemo { public static void main(String[] args) { Writer writer = new Writer("沉默王二",18); System.out.println("toString:" + writer); System.out.println("hashCode:" + writer.hashCode()); System.out.println("name:" + writer.name()); System.out.println("age:" + writer.age()); Writer writer1 = new Writer("沉默王二", 18); System.out.println("equals:" + (writer.equals(writer1))); } }
程序输出的结果如下所示:
toString:Writer[name=沉默王二, age=18]
hashCode:1130697218
name:沉默王二
age:18
equals:true
1
2
3
4
5
不错不错,真香,以后定义不可变类时就简单了,强烈希望这个特性在下个版本中转正。
03、switch 表达式
关于 switch 表达式,我在之前的一篇文章中已经详细说明了,点击传送门可以跳转过去看看。两周时间过去了,switch 表达式终于“媳妇熬成婆”,转正了,恭喜恭喜。
记得这篇文章发表到掘金的时候,被喷子各种无脑 diss,说:“还以为你有什么技巧,没想到用的是 Java 13,可我们还停留在 Java 8 啊!”这显然是一种固步自封的心态,非常不可取,程序员不应该这样。一个最简单的道理就是,Java 6 当年也很经典,不是被 Java 8 取代了吗?随着时间的推移,Java 8 早晚会被更划时代的新版本取代——总要进步嘛。
关于 switch 表达式,这里就简单地搬个例子给你瞧瞧:
public class SwitchDemo { enum PlayerTypes { TENNIS, FOOTBALL, BASKETBALL, PINGPANG, UNKNOWN } public static void main(String[] args) { System.out.println(createPlayer(PlayerTypes.BASKETBALL)); } private static String createPlayer(PlayerTypes playerType) { return switch (playerType) { case TENNIS -> "网球运动员费德勒"; case FOOTBALL -> "足球运动员C罗"; case BASKETBALL -> "篮球运动员詹姆斯"; case PINGPANG -> "乒乓球运动员马龙"; case UNKNOWN -> throw new IllegalArgumentException("未知"); }; } }
除了可以使用 -> 的新式语法,还可以作为 return 结果,真香。
04、Text Blocks
在文本块(Text Blocks)出现之前,如果我们需要拼接多行的字符串,就需要很多英文双引号和加号,看起来就好像老太婆的裹脚布,非常不雅。如果恰好要拼接一些 HTML 格式的文本(原生 SQL 也是如此)的话,还要通过空格进行排版,通过换行转义符 \n 进行换行,这些繁琐的工作对于一名开发人员来说,简直就是灾难。
public class OldTextBlock { public static void main(String[] args) { String html = "<html>\n" + " <body>\n" + " <p>Hello, world</p>\n" + " </body>\n" + "</html>\n"; System.out.println(html); } }
Java 14 就完全不同了:
public class NewTextBlock { public static void main(String[] args) { String html = """ <html> <body> <p>Hello, world</p> </body> </html> """; System.out.println(html); } }
多余的英文双引号、加号、换行转义符,统统不见了。仅仅是通过前后三个英文双引号就实现了。我只能说,香,它真的香!
05、最后,一定会有不少读者想要问我怎么学习 Java 的,那我干脆就把我看过的优质书籍贡献出来:
1)入门版:《Head First Java》、《Java 核心技术卷》
2)进阶版:《Java编程思想》、《Effective Java》、《Java网络编程》、《代码整洁之道》
3)大牛版:《Java并发编程》、《深入理解Java虚拟机》、《Java性能权威指南》、《重构》、《算法》
就先介绍这么多,希望对那些不知道看什么书的同学有所帮助。