• Java SE 16 record 类型说明与使用


    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

  • 相关阅读:
    《JavaScript 闯关记》之 BOM
    《JavaScript 闯关记》之单体内置对象
    《JavaScript 闯关记》之基本包装类型
    《JavaScript 闯关记》之正则表达式
    《JavaScript 闯关记》之函数
    《JavaScript 闯关记》之数组
    被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」
    「前端开发者」如何把握住「微信小程序」这波红利?
    android开发之路13(实际开发常见问题及解决办法ING)
    android开发之路12(android四大组件&Fragment&AsyncTask类)
  • 原文地址:https://www.cnblogs.com/greyzeng/p/16723149.html
Copyright © 2020-2023  润新知