Ответы на вопросы по ревью 4. Java io. Ключевым понятием здесь является понятие потока
Скачать 1.93 Mb.
|
Клонирование1. Что такое клонирование?Иногда необходимо на основе существующего объекта создать второй такой же - то есть создать его клон. Это процесс в Java называется клонированием. Для клонирования объекта в Java можно воспользоваться тремя способами: Переопределение метода clone() и реализация интерфейса Cloneable(). Использование конструктора копирования. Использовать для клонирования механизм сериализации. 2. Переопределение метода clone()Класс Object определяет метод clone(), который создает копию объекта. Если вы хотите, чтобы экземпляр вашего класса можно было клонировать, необходимо переопределить этот метод и реализовать интерфейс Cloneable. Интерфейс Clonable - это интерфейс маркер, он не содержит ни методов, ни переменных. Интерфейсы маркер просто определяют поведение классов. Object.clone() выбрасывает исключение CloneNotSupportedException при попытке клонировать объект не реализующий интерфейс Cloneable. Метод clone() в родительском классе Object является protected, поэтому желательно переопределить его как public. Реализация по умолчанию метода Object.clone() выполняет неполное/поверхностное (shallow) копирование. Рассмотрим пример: Пример 1. Поверхностное клонированиеpublic class Car implements Cloneable { private String name; private Driver driver; public Car(String name, Driver driver) { this.name = name; this.driver = driver; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Driver getDriver() { return driver; } public void setDriver(Driver driver) { this.driver = driver; } @Override public Car clone() throws CloneNotSupportedException { return (Car) super.clone(); } } public class Driver implements Cloneable { private String name; private int age; public Driver(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public Driver clone() throws CloneNotSupportedException { return (Driver) super.clone(); } } public class CloneCarDemo { public static void main(String[] args) throws CloneNotSupportedException { Car car = new Car("Грузовик", new Driver("Василий", 45)); Car clonedCar = car.clone(); System.out.println("Оригинал:\t" + car); System.out.println("Клон: \t" + clonedCar); Driver clonedCarDriver = clonedCar.getDriver(); clonedCarDriver.setName("Вася"); System.out.println("Оригинал после изменения имени водителя:\t" + car); System.out.println("Клон после изменения имени водителя: \t\t" + clonedCar); } } В этом примере клонируются объект класса Car. Клонирование выполняется поверхностное - новый объект clonedCar содержит ссылку на тот же объект класса Driver, что и объект car. Если вас это не устраивает, то необходимо самим написать "глубокое" клонирование - создать новый объект класса Driver. Перепишем метод clone() класса Car: Пример 2. Глубокое клонирование@Override public Car clone() throws CloneNotSupportedException { Car newCar = (Car) super.clone(); Driver driver = this.getDriver().clone(); newCar.setDriver(driver); return newCar; } 3. Конструктор копированияЕще один вариант клонирования объекта - это конструктор копирования. Создается конструктор, принимающий на вход объект того же класса, который необходимо клонировать: Пример 3. Конструктор копирования с поверхностным клонированиемpublic class Car implements Cloneable { private String name; private Driver driver; public Car(String name, Driver driver) { this.name = name; this.driver = driver; } /** * Конструктор копирования. * * @param otherCar */ public Car(Car otherCar) { this(otherCar.getName(), otherCar.getDriver()); } public String getName() { return name; } public void setName(String name) { this.name = name; } public Driver getDriver() { return driver; } public void setDriver(Driver driver) { this.driver = driver; } } Опять же - пример показывает неглубокое клонирование. Перепишем конструктор для реализации "глубокого" копирования: Пример 4. Конструктор копирования с "глубоким" клонированиемpublic Car(Car otherCar) throws CloneNotSupportedException { this(otherCar.getName(), otherCar.getDriver().clone()); } Клонирование объекта создает копию существующего объекта для изменения или перемещения скопированного объекта, не затрагивая исходный объект. В Java управление объектами осуществляется с помощью ссылочных переменных, и нет оператора для фактического копирования объекта. Помните, что оператор присваивания дублирует ссылку, а не объект. |