Философия Java


Успешное клонирование


Теперь, когда вы познакомились с нюансами реализации метода clone(), можно приступить к созданию классов, дублируемых с созданием локальных копий.

//: Приложение А:LocalCopy.java

// Создание локальных копий используя метод clone().

import java.util.*;

class MyObject implements Cloneable { int i; MyObject(int ii) { i = ii; } public Object clone() { Object o = null; try { o = super.clone(); } catch(CloneNotSupportedException e) { System.err.println("MyObject не может быть клонирован"); } return o; } public String toString() { return Integer.toString(i); } }

public class LocalCopy { static MyObject g(MyObject v) { // Передача ссылки, которая изменяет внешний объект:

v.i++; return v; } static MyObject f(MyObject v) { v = (MyObject)v.clone(); // Локальная копия

v.i++; return v; } public static void main(String[] args) { MyObject a = new MyObject(11); MyObject b = g(a); // Проверка ссылок (не объектов) на равенство

if(a == b) System.out.println("a == b"); else System.out.println("a != b"); System.out.println("a = " + a); System.out.println("b = " + b); MyObject c = new MyObject(47); MyObject d = f(c); if(c == d) System.out.println("c == d"); else System.out.println("c != d"); System.out.println("c = " + c); System.out.println("d = " + d); } } ///:~

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

Метод Object.clone() определяет размер объекта, выделяет необходимое количество свободной памяти для создания копии и осуществляет побитное копирование. Эта процедура называется поразрядным копированием и является сутью клонирования. Но перед выполнением этих операций Object.clone() выполняет проверку, является ли копируемый объект клонируемым - то есть, реализует ли он интерфейс Cloneable. Если нет - Object.clone() возвращает исключительную ситуацию CloneNotSupportedException, сигнализирующую о том, что данный объект не может быть клонирован. Таким образом вы должны поместить вызов метода super.clone( ) в блок операторов try-catch, чтобы перехватывать и обрабатывать подобные ситуации, которые не должны возникнуть (поскольку вы реализуете интерфейс Clonable).




Начало  Назад  Вперед