查看原文
其他

Java 14 新特性之JEP 359: Records(Preview)

码农小胖哥 码农小胖哥 2020-10-16

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 方法。
  • 覆写了 超类 ObjectequalshashCodetoString 方法。

虽然我们可以借助于第三方框架或者 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]

参考资料

[1]

felord.cn: https://felord.cn




    您可能也对以下帖子感兴趣

    文章有问题?点此查看未经处理的缓存