作者:Grey
原文地址:
部落格園:Java SE 16 record 型別說明與使用
CSDN:Java SE 16 record 型別說明與使用
record 是 Java SE 16 的新特性
假設我們想建立一個不可變的類 Point,它有 x 和 y 的座標。我們想範例化Point物件,讀取它們的欄位,並將它們儲存在 List 中或在 Map 中作為鍵值使用。
我們可以這樣實現 Point 類
public class Point {
private final int x;
private final int y;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
if (x != point.x) return false;
return y == point.y;
}
@Override
public int hashCode() {
int result = x;
result = 31 * result + y;
return result;
}
@Override
public String toString() {
return "Point{" + "x=" + x + ", y=" + y + '}';
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
如上程式碼中重複寫了很多模板程式碼,使用 Lombok,程式碼可以簡化成如下方式
@AllArgsConstructor
@Getter
@EqualsAndHashCode
@ToString
public class Point {
private final int x;
private final int y;
}
現在有了 record 上述所有程式碼可以簡化為
public record Point(int x, int y) {}
使用javac Point.java && javap Point
,我們可以檢視到 Point 反編譯後的結果
public final class Point extends java.lang.Record {
public Point(int, int);
public final java.lang.String toString();
public final int hashCode();
public final boolean equals(java.lang.Object);
public int x();
public int y();
}
和我們最初始的 Point 類定義是一樣的,所以 record 可以大量簡化程式碼的編寫。
我們可以像正常使用類一樣使用 record
範例程式碼
public class App {
public static void main(String[] args) {
Point p = new Point(3, 4);
int x = p.x();
int y = p.y();
System.out.println(x + " " + y);
Point p2 = new Point(3, 4);
Point p3 = new Point(7, 5);
System.out.println(p2.equals(p)); // 輸出 true
System.out.println(p2.equals(p3)); // 輸出 false
}
}
record 可以通過如下方式來實現多建構函式
public record Point(int x, int y) {
public Point() {
this(3, 3);
}
public Point(int v) {
this(v, v + 3);
}
}
record 中可以包括 static 型別變數,範例如下
public record Point(int x, int y) {
private static final int ZERO = 0;
private static long count = 0;
public Point() {
this(ZERO, ZERO);
synchronized (Point.class) {
count++;
}
}
public static synchronized long getCount() {
return count;
}
public Point(int v) {
this(v, v + 3);
}
}
如果要覆蓋 record 的預設建構函式,則函數入參一定要和 record 的入參保持一致,否則會報錯
正確
public record Point(int x, int y) {
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
錯誤
public record Point(int x, int y) {
public Point(int m, int n) {
this.x = m;
this.y = n;
}
}
record 中可以自定義非 static 方法,例如
public record Point(int x, int y) {
public double distanceTo(Point target) {
int dx = target.x() - this.x();
int dy = target.y() - this.y();
return Math.sqrt(dx *dx + dy* dy);
}
}
呼叫方法
public class App {
public static void main(String[] args) {
Point from = new Point(17, 3);
Point to = new Point(18, 12);
double distance = from.distanceTo(to);
System.out.println(distance);
}
}
record 也可以實現介面,但是無法繼承類
正確
public record Point(int x, int y) implements WithXCoordinate {}
public interface WithXCoordinate {
int x();
}
錯誤
public record Point(int x, int y) extends WithXCoordinate {}
public class WithXCoordinate {
int x(){}
}
record 也無法被其他類繼承,例如
錯誤
public record Point(int x, int y) {}
public class WithXCoordinate extends Point{
int x(){}
}
本文來自部落格園,作者:Grey Zeng,轉載請註明原文連結:https://www.cnblogs.com/greyzeng/p/16723149.html