Copy classes java это

How do we copy objects in java?

In Java you can copy an object in several ways, among them, copy constructor and the clone method are the mostly used.

Using copy constructor

Generally, the copy constructor is a constructor which creates an object by initializing it with an object of the same class, which has been created previously. Java does support for copy constructors but you need to define them yourself.

Example

In the following Java example, we a have a class with two instance variables name and age and a parameterized constructor initializing these variables.

Then, we have another constructor which accepts an object of the current class and initializes the instance variables with the variables of this object.

If you instantiate this class using the second constructor by passing an object to it, this results an object which is the copy of the one which you passed as an argument.

import java.util.Scanner; public class Student < private String name; private int age; public Student(String name, int age)< this.name = name; this.age = age; >public Student(Student std) < this.name = std.name; this.age = std.age; >public void displayData() < System.out.println("Name : "+this.name); System.out.println("Age : "+this.age); >public static void main(String[] args) < Scanner sc =new Scanner(System.in); System.out.println("Enter your name "); String name = sc.next(); System.out.println("Enter your age "); int age = sc.nextInt(); Student std = new Student(name, age); System.out.println("Contents of the original object"); std.displayData(); System.out.println("Contents of the copied object"); Student copyOfStd = new Student(std); copyOfStd.displayData(); >>

Output

Enter your name Krishna Enter your age 20 Contents of the original object Name : Krishna Age : 20 Contents of the copied object Name : Krishna Age : 20

Using the clone method

The clone() method of the class java.lang.Object accepts an object as a parameter, creates and returns a copy of it.

Читайте также:  Styling for tables css

Example

In the following Java example, we a have a class with two instance variables name and age and a parameterized constructor initializing these variables.

From the main method we are creating an object of this class and generating a copy of it using the clone() method.

import java.util.Scanner; public class CloneExample implements Cloneable < private String name; private int age; public CloneExample(String name, int age)< this.name = name; this.age = age; >public void displayData() < System.out.println("Name : "+this.name); System.out.println("Age : "+this.age); >public static void main(String[] args) throws CloneNotSupportedException < Scanner sc =new Scanner(System.in); System.out.println("Enter your name "); String name = sc.next(); System.out.println("Enter your age "); int age = sc.nextInt(); CloneExample std = new CloneExample(name, age); System.out.println("Contents of the original object"); std.displayData(); System.out.println("Contents of the copied object"); CloneExample copiedStd = (CloneExample) std.clone(); copiedStd.displayData(); >>

Output

Enter your name Krishna Enter your age 20 Contents of the original object Name : Krishna Age : 20 Contents of the copied object Name : Krishna Age : 20

Источник

Метод Clone() в Java

В этом посте будет обсуждаться, как скопировать объект в Java с помощью clone() метод в Object class и один, предоставленный Apache Commons Lang. Мы также подробно обсудим мелкое и глубокое копирование.

Клонирование объекта создает копию существующего объекта для изменения или перемещения скопированного объекта, не затрагивая исходный объект. В Java управление объектами осуществляется с помощью ссылочных переменных, и нет оператора для фактического копирования объекта. Помните, что оператор присваивания дублирует ссылку, а не объект.

1. Использование Object.clone() метод

Классы, которым нужна функция копирования, могут использовать Object.clone() метод, который создает и возвращает копию объекта. Прототип Object.clone() является

В качестве возвращаемого типа Object.clone() является Object , приведение типов необходимо для присвоения возвращаемой ссылки Object ссылке на объект.

Все задействованные классы должны реализовывать Cloneable интерфейс для указания Object.clone() метод о том, что для этого метода разрешено создавать полевые копии экземпляров этого класса. Вызов метода clone объекта для экземпляра, который не реализует Cloneable интерфейс приводит к CloneNotSupportedException .

Поскольку каждый класс неявно расширяет Object учебный класс, Object.clone() является переопределяемым методом. Поскольку Java поддерживает ковариантные возвращаемые типы, возвращаемый тип clone() можно изменить с Object на тип клонируемого объекта, и clone() должен переопределить защищенный Object.clone() метод с общедоступным методом.

The clone() ведет себя так же, как Копировать конструктор. Он называет clone() метод своего родительского класса для получения копии и т. д., пока он в конечном итоге не достигнет класса Object. clone() метод, который создает новый экземпляр того же класса, поскольку объект копирует все поля в новый экземпляр.

1. Object.clone() не будет работать с интерфейсами и абстрактными классами.

Единственный способ использовать Object.clone() метод, если класс объекта известен, т. е. мы не можем получить доступ к clone() метод для абстрактного типа, так как большинство интерфейсов и абстрактных классов в Java не определяют общедоступный clone() метод.

Например, нельзя вызвать clone() в ссылке на карту в Java, потому что карта не указывает общедоступного clone() метод. Только реализации карты, такие как HashMap а также LinkedHashMap имеют clone() методы, но носить с собой тип класса объекта не рекомендуется, и это противоречит принципу “программа для интерфейса, а не для реализации”.

2. Реализация по умолчанию Object.clone() метод возвращает Неглубокое копирование.

При неглубоком копировании, если значение поля является примитивным типом, оно копирует свое значение; в противном случае, если значение поля является ссылкой на объект, оно копирует ссылку и, следовательно, ссылается на тот же объект. Теперь, если один из этих объектов изменен, изменение будет видно в другом. В Глубокое копирование, в отличие от мелкой копии, объекты, на которые есть ссылки, не являются общими; вместо этого новые объекты создаются для любых объектов, на которые есть ссылки.

Shallow Copy

Следующая программа демонстрирует использование Object.clone() метод, используя его реализацию по умолчанию, которая возвращает поверхностную копию. Мы рассмотрим глубокое копирование с помощью clone() метод в следующем разделе.

Источник

Java: Copying Objects

Unlike C++ and JavaScript, there’s no easy and direct way of copying objects. The built-in clone capability is poorly designed and is rarely the best alternative.

This article lists the pros and cons of all the common approaches, with examples.

  • Copy Constructors
  • Copy Factory Methods
  • Serialization
  • Cloning
  • Copy methods
  • Builders

Copy Constructors

public class Car < private String make; private int doors; private Motor motor; private Gearbox gearbox; public Car(Car other) < this.make = other.make; this.doors = other.doors; this.motor = other.motor; this.gearbox = other.gearbox; > … >
Car copy = new Car(original);

Note that this produces a shallow copy. (See Shallow vs Deep Copy, with examples.) If you do original.getGearbox().setGear(4) , then copy ‘s gear will change as well. To get a deep copy, change to…

public Car(Car other) < this.make = other.make; this.doors = other.doors; this.motor = new Motor(other.motor); this.gearbox = new Gearbox(other.gearbox); > …

Copy Constructors and Inheritance

Adding a subclass, Taxi is straight forward:

public class Taxi extends Car < boolean isAvailable; public Taxi(Taxi other) < // Invoke copy constructor of Car super(other); this.isAvailable = other.isAvailable; > … >

However, when using a copy constructor you must know the actual runtime type. If you’re not careful, you may inadvertently create a Car when trying to create a copy of a Taxi .

Car copy = new Car(someCar); // What if someCar is a Taxi?!

You could use instanceof (often considered bad practice) or the visitor pattern to sort it out, but in this case you’re probably better off using one of the other techniques described in this article.

Pros

  • Simple and straight forward
  • Easy to get right, debug and maintain
  • No casts required

Cons

Copy Factory Methods

A copy factory method encapsulates the object copying logic and provides finer control over the process. In the example below, this capability is used to tacle the problem of inheritance mentioned in the previous section.

public class CarFactory < … public Car copyOf(Car c) < Classcls = c.getClass(); if (cls == Car.class) < return new Car( c.make, c.doors, c.motor, c.gearbox); > if (cls == Taxi.class) < return new Taxi( c.make, c.doors, c.motor, c.gearbox, ((Taxi) c).isAvailable); > if (cls == Ambulance.class) < return new Ambulance( c.make, c.doors, c.motor, c.gearbox, ((Ambulance) c).beaconsOn); > throw new IllegalArgumentException("Can't copy car of type " + cls); > … >
Car copy = myCarFactory.copyOf(car);

Pros

Cons

  • Another level of indirection
  • Not as easy to extend
  • Might require access to internal state

Serialization / Deserialization

By serializing an object into a byte array, then deserializing the byte array back into an object, you end up with a deep copy of the original.

// Serialize to byte[] ByteArrayOutputStream os = new ByteArrayOutputStream(); new ObjectOutputStream(os).writeObject(original); byte[] buf = os.toByteArray(); // Deserialize back into a Car object ByteArrayInputStream is = new ByteArrayInputStream(buf); Car copy = (Car) new ObjectInputStream(is).readObject(); 

With Apache Commons Lang the whole snippet can be replaced by…

…which does not throw any checked exceptions and infers the correct return type.

Note that the serialization mechanism does not call any constructors. Customizing the serialization / deserialization—which is needed when dealing with non-serializable external classes—requires you to «override» private methods. This kind of unintuitive semantics makes it tricker to understand, debug, and maintain code.

Pros

  • Handles inheritance
  • Very little boilerplate
  • Provides deep copying out of the box
    • Even object graphs with cycles!

    Cons

    • All objects must be Serializable
    • Requires extra temporary memory
    • Relies on black magic
      • Overriding private methods
      • No constructor calls

      That being said, any serialization library would do. If you already have for example Jackson or Gson set up, you can reuse your ObjectMapper or Gson objects for copying purposes, and do away without «black magic» and casts.

      Object.clone

      Object.clone offers a shortcut for creating exact, field-by-field, copies of objects. A lot of the boilerplate otherwise required in copy constructors or static factory methods goes away.

      class Car implements Cloneable < private String make; private int doors; private Motor motor; private Gearbox gearbox; … @Override public Car clone() < try < Car c = (Car) super.clone(); // Already copied by Object.clone // c.doors = doors; c.motor = motor.clone(); c.gearbox = gearbox.clone(); // No need to clone immutable objects // c.make = make; return c; > catch (CloneNotSupportedException e) < // Will not happen in this case return null; > > … >
      Car copy = (Car) originalCar.clone();

      Unfortunately the cloning API is poorly designed and should almost always be avoided. Copying arrays is a notable exception where cloning is the preferred method.

      Pros

      Cons

      • Casts required
      • No constructors called
      • Incompatible with final fields
      • CloneNotSupported is checked
      • Can’t opt out from being Cloneable

      Simple copy method

      class Car < … public Car copy() < Car copy = new Car(); copy.make = this.make; copy.doors = this.doors; copy.motor = this.motor.copy(); copy.gearbox = this.gearbox.copy(); return copy; > … >

      As it stands, it’s not easy to add a subclass to the above example. If a subclass, say Taxi , where to override Car.copy , it would need to call super.copy() to make sure private fields in Car are copied. super.copy() however, would return a Car object, which would be of little use to Taxi.copy since it needs to return a Taxi object.

      If your situation involves a class hierarchy, a better solution would be:

      class Car < … protected void copyFrom(Car car) < this.make = car.make; this.doors = car.doors; this.motor = car.motor; this.gearbox = car.gearbox; > public Car copy() < Car copy = new Car(); copy.copyFrom(this); return copy; > … > class Taxi extends Car < … protected void copyFrom(Taxi taxi) < super.copyFrom(taxi); this.isAvailable = taxi.isAvailable; > public Taxi copy() < Taxi copy = new Taxi(); copy.copyFrom(this); return copy; > … >

      In the above example, the public copy method delegates to the protected copyFrom method which can easily be overridden in subclasses.

      Pros

      • Simple and straight forward
      • Easy to understand and debug
      • No casts required
      • Don’t need to know the runtime type

      Cons

      Builders

      If the class has a builder, you could add a from method that initiates the builder with the values from a given object.

      class Car < public static class Builder < private String make; private int doors; … public Builder() < >public Builder make(String make) < this.make = make; return this; > // other builder methods… public Builder from(Car toCopyFrom) < make(toCopyFrom.make); doors(toCopyFrom.doors); … return this; > public Car build() < return new Car( make, doors, buildMotor(), buildGearbox()); > > // Rest of Car class … >
      Car copy = new Car.Builder() .from(original) .build();

      This is precisely what the Immutables library does when generating a builder for value classes.

      Pros

      Cons

      Источник

Оцените статью