LoginSignup
0
1

More than 3 years have passed since last update.

JavaのRecordに対するcloneメソッドの実装

Last updated at Posted at 2020-10-30

Java 15で2nd previewとなっているRecordにcloneメソッドを実装し、deep copyできるようにします。
特にこれといって使う場面は浮かびませんが、いつか使うかもしれないので備忘録に。
ポイントはsuper.clone()を使わずにコンストラクタでcloneを作ることくらいです。

環境

Java 15(Oracle Open JDK)
IntelliJ IDEA Community版
Windows

※IntelliJでRecordを使うための設定は以下を参考にしてください(手前味噌ですが)。
https://qiita.com/tora_kouno/items/58eff9f4eb99a941fd41

実装

clone実装前

ExampleRecord.java

public record ExampleRecord(String name, int age, ExampleDto dto) {
}

ExampleDto.java

public class ExampleDto {
  private String name;
  private int age;
  private NodeDto node;
  // setter, getter, toStringは省略
}

NodeDto.java

public class NodeDto {
  private String name;
  // setter, getter, toStringは省略
}

clone実装後

ExampleRecord.java

public record ExampleRecord(String name, int age, ExampleDto dto) {
  @Override
  public ExampleRecord clone() {
    try {
      return new ExampleRecord(this.name, this.age, this.dto.clone());
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
    return null;
  }
}

ExampleDto.java

public class ExampleDto implements Cloneable {
  private String name;
  private int age;
  private NodeDto node;
  // setter, getter, toStringは省略

  @Override
  public ExampleDto clone() throws CloneNotSupportedException {
    ExampleDto copy = (ExampleDto) super.clone();
    copy.node = this.node.clone();
    return copy;
  }
}

NodeDto.java

public class NodeDto implements Cloneable {
  private String name;
  // setter, getter, toStringは省略

  @Override
  public NodeDto clone() throws CloneNotSupportedException {
    return (NodeDto) super.clone();
  }
}

試す

実装

Main.java


public class Main {
  public static void main(String[] args) {
    ExampleDto dto = new ExampleDto();
    NodeDto nodeDto = new NodeDto();
    nodeDto.setName("node1");
    dto.setNode(nodeDto);
    dto.setName("dto1");
    dto.setAge(1);
    ExampleRecord exampleRecord = new ExampleRecord("record1", 2, dto);
    System.out.println("exampleRecord:"+exampleRecord);// 1
    dto.setName("dto2");
    nodeDto.setName("node2");
    System.out.println("exampleRecord:"+exampleRecord);// 2

    ExampleRecord clone = exampleRecord.clone();
    System.out.println("clone:"+clone);// 3
    dto.setName("dto3");
    nodeDto.setName("node3");
    System.out.println("clone:"+clone);// 4
  }
}

実行結果

1.

exampleRecord:ExampleRecord[name=record1, age=2, dto=ExampleDto{name='dto1', age=1, node=NodeDto{name='node1'}}]

2.

exampleRecord:ExampleRecord[name=record1, age=2, dto=ExampleDto{name='dto2', age=1, node=NodeDto{name='node2'}}]

3.

clone:ExampleRecord[name=record1, age=2, dto=ExampleDto{name='dto2', age=1, node=NodeDto{name='node2'}}]

4.

clone:ExampleRecord[name=record1, age=2, dto=ExampleDto{name='dto2', age=1, node=NodeDto{name='node2'}}]

1->2ではDtoの中身が変わってしまっていますが、3->4では別インスタンスであるためdto.setName("dto3");nodeDto.setName("node3");の影響を受けず、問題なくcloneされていることがわかります。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1