How do I copy an object in Java?

There are several ways to copy an object in Java. Here are a few options:

  1. Shallow copy: You can create a new object and copy the reference of the original object to the new object. This is known as a shallow copy. However, this does not create a new copy of the object, it just creates a new reference to the same object. Any changes made to the object through the new reference will be reflected in the original object as well. Here's an example of how you can do a shallow copy:
class MyClass {
  int value;

  public MyClass(int value) {
    this.value = value;
  }
}

public class Main {
  public static void main(String[] args) {
    MyClass original = new MyClass(1);
    MyClass copy = original;

    copy.value = 2;
    System.out.println(original.value);  // Outputs 2
  }
}
  1. Deep copy: To create a new copy of an object and all its fields, you can use deep copying. One way to do this is to use the clone method of the Object class. However, this method is protected, so you need to override it in your class and make it public. Here's an example of how you can do a deep copy using the clone method:
class MyClass implements Cloneable {
  int value;

  public MyClass(int value) {
    this.value = value;
  }

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

public class Main {
  public static void main(String[] args) {
    MyClass original = new MyClass(1);
    MyClass copy;
    try {
      copy = original.clone();
      copy.value = 2;
      System.out.println(original.value);  // Outputs 1
    } catch (CloneNotSupportedException e) {
      e.printStackTrace();
    }
  }
}
  1. Serialization: Another way to create a deep copy of an object is to use serialization. Serialization is the process of converting an object into a stream of bytes, which can then be saved to a file or transmitted over a network. To deserialize the object, you can read the bytes from the file or network and recreate the object. Here's an example of how you can do a deep copy using serialization:
import java.io.*;

class MyClass implements Serializable {
  int value;

  public MyClass(int value) {
    this.value = value;
  }
}

public class Main {
  public static void main(String[] args) {
    MyClass original = new MyClass(1);
    MyClass copy;
    try {
      // Serialize the object
      ByteArrayOutputStream baos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(baos);
      oos.writeObject(original);
      oos.close();

      // Deserialize the object
      ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
      ObjectInputStream ois = new ObjectInputStream(bais);
      copy = (MyClass)