首页 > 编程语言 >Java SE 16 record 类型说明与使用

Java SE 16 record 类型说明与使用

时间:2022-09-23 16:22:54浏览次数:81  
标签:Java Point int 16 final record return public

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

标签:Java,Point,int,16,final,record,return,public
From: https://www.cnblogs.com/greyzeng/p/16723149.html

相关文章

  • 对Java小白自学的建议
    1.一套比较好的Java学习教程真的非常重要,我相信很多人在自学Java的时候都会去网上找各种教程,但基本都是非常零散和拼凑的。而且讲的深度也不一样,所以我首先建议想学习Java......
  • Vue中使用benz-amr-recorder插件实现播放amr音频文件以及在线url跨域问题解决
    场景需要做一个Android端和Web端的聊天室,Android端的录音音频文件为.amr格式,除了通过后台server端转码之后,是否可以通过插件在前端直接播放amr的音频文件。benz-amr-rec......
  • JavaScript
    JavaScript的组成ECMAScript : 定义语言规范DOM: 操作文档的APIBOM: 操作浏览器的API......
  • java eclipse 声明与期望的包不匹配
     只需要把需要执行的java拖动到src文件就可以执行了,不在期望的包里面 publicclasstest{publicstaticvoidmain(String[]args){ AAc=newAA();......
  • java举例体会反射的动态性
    importjava.lang.reflect.Constructor;importjava.util.Random;publicclassReflectionTest{publicstaticvoidmain(String[]args)throwsException{......
  • JAVA基础Day3-用户交互Scanner/顺序结构/选择结构/循环结构
    一、用户交互ScannerJAVA提供了一个工具类,可以用来获取用户的输入。java.util.Scanner是Java5的新特征,可以通过Scanner类来获取用户的输入。基本语法:Scanners=new......
  • java ArrayList的深拷贝与浅拷贝
    一、前言:ArrayList是我们经常会用到的集合类,有时候我们为了要不改变原来的数据需要重新拷贝一个新的ArrayList,今天在使用ArrayList拷贝时遇到了一些问题,这里整理并记录一......
  • java使用ClassLoader加载配置文件(properties)
    importjava.io.File;importjava.io.FileInputStream;importjava.io.FileNotFoundException;importjava.io.InputStream;importjava.util.Properties;publiccl......
  • Java Array、String、List的切片操作
    Array数组int[]test_int=newint[]{1,2,3,4,5};test_int=Arrays.copyOfRange(test_int,1,4);System.out.println(Arrays.toString(test_int));......
  • JavaScript 对象
    1.创建对象对象以键值对的方式进行存储,是一组无序的相关属性和函数方法的集合,可以通过键(属性名)访问这些值。在JavaScript中所有东西都是对象。字面量创建varobj=......