Java 14 新特性之JEP 359: Records(Preview)
1. 前言
本月(2020-03) Java 14 就该正式发布了,有一个 Java 社区呼唤已久的特性将作为 preview feature包含在 Java 14 中 ,这就是 JEP 359: Records。换句话说效果类似 lombok 的 @Data
注解,但是又不完全是, 在合适的场景中我们终于不用编写样板代码了。今天我们就来感受一下。欢迎加入[微信圈子] 交流编程经验。
其实更像 Jvm 语言 kotlin 中的 data class
2. 传统数据类
我们先来看看现在我们如何声明一个数据类:
public class Range {
private final int min;
private final int max;
public Range(int min, int max) {
this.min = min;
this.max = max;
}
public int getMin() {
return min;
}
public int getMax() {
return max;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Range range = (Range) o;
return min == range.min && max == range.max;
}
@Override
public int hashCode() {
return Objects.hash(min, max);
}
@Override
public String toString() {
return "Range{" +
"min=" + min +
", max=" + max +
'}';
}
}
我们来看看这个类的特点:
没有无参构造方法,需要初始化时对成员变量赋值 成员变量只有 getter 方法。 覆写了 超类 Object
的equals
、hashCode
、toString
方法。
虽然我们可以借助于第三方框架或者 IDE 很容易编写这些样板代码,但是总归要写这些样板代码不是吗?
3. 新的 Java Records
上面的冗长的代码在 Java 14 中我们可以这么写:
public record Range(int min, int max) {}
没错就是这个简单!这个语法糖是不是有 “卧槽” 的感觉?我们声明这种类使用 record 标识(目前不知道 record 会不会上升到关键字的高度)。当你用 record 声明一个类时,该类将自动拥有以下功能:
获取成员变量的简单方法,以上面代码为例 min()
和max()
。注意区别于我们平常getter的写法。一个 equals
方法的实现,执行比较时会比较该类的所有成员属性重写 equals
当然要重写hashCode
一个可以打印该类所有成员属性的 toString
方法。请注意只会有一个构造方法。
因为这个特性是 preview feature,默认情况下是无法编译和执行的。同样以上面为例我们需要执行:
$ javac -d classes --enable-preview --release 14 Range.java
$ java -classpath classes --enable-preview Range
在 Jshell 中运行
jshell> Range r = new Range(10, 20);
r ==> Range[min=10, max=20]
jshell> r.min()
$5 ==> 10
jshell> r.toString()
$6 ==> "Range[min=10, max=20]"
jshell> r
r ==> Range[min=10, max=20]
虽然 record 声明的类没有 final
关键字,实际上它是一个不可变类。除了一些限制外,它依旧是一个普通的Java
类。因此,我们可以像添加普通类一样添加逻辑。我们可以在构造实例时强制执行前提条件:
public record Range(int min, int max) {
public Range {
if (min >= max)
throw new IllegalArgumentException("min should be less than max");
}
}
另外我们也可以给 Records 类增加普通方法、静态属性、静态方法,这里不再举例;
**为了简化语法糖的推理,不能在类内声明成员属性。**以下是错误的示范:
public record Range(int min, int max) {
// 错误的示范
private String name;
}
4. 总结
今天对即将到来的 Java 14 的预览特性 Java Records 进行了介绍。随着 Java 版本迭代的加快,Java 也逐渐跟上了时代的步伐,希望这门伟大的语言继续焕发生机。更多我的技术文章请访问 felord.cn[1]。
参考资料
felord.cn: https://felord.cn