5

Java SE 16 record 类型说明与使用 - Grey Zeng

 1 year ago
source link: https://www.cnblogs.com/greyzeng/p/16723149.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

Java SE 16 record 类型说明与使用

作者:Grey

原文地址:

博客园:Java SE 16 record 类型说明与使用

CSDN:Java SE 16 record 类型说明与使用

说明#

record 是 Java SE 16 的新特性

record 的使用场景#

假设我们想创建一个不可变的类 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(){}
}

源码#

hello-record

参考文档#

Java Records


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK