В этом посте мы увидим, как сделать копию объекта на Java. В наших приложениях JavaBeans играют очень важную роль. Однако иногда нам просто нужно сделать копию нашего JavaBeans, чтобы внести изменения в копию и сохранить исходный объект без изменений.
Есть два способа, которыми это может быть достигнуто в Java, в зависимости от уровня доступа к вашим компонентам.
- Использование Object.clone ()
- Использование BeanUtils
Копирование с использованием Object.clone ()
Этот метод можно использовать, когда у вас есть доступ к исходному коду ваших классов бинов. Этот метод требует вашего JavaBeans для реализации клонируемого интерфейса. Интерфейс Cloneable — это интерфейс маркера, который указывает, что объект позволяет клонировать себя. Мы можем вызывать метод Object.clone () только для объектов, классы которых реализуют интерфейс Cloneable. Если мы попытаемся вызвать метод clone () для объекта класса, который не реализует интерфейс Cloneable, мы получим исключение CloneNotSupportedException.
Также обратите внимание, что метод clone () — это защищенный метод, поэтому вам, скорее всего, потребуется создать открытый метод в классе вашего компонента с именем clone (), чтобы имитировать функциональность.
Мы собираемся продемонстрировать оба вышеупомянутых метода, используя простой класс Employee. Этот класс будет содержать экземпляр другого javabean-адреса. В следующем примере мы увидим, как мы можем получить глубокую копию наших компонентов.
Следующий код демонстрирует использование Object.clone ()
Address.java
class Address {
private int houseNo;
public int getHouseNo() {
return houseNo;
}
public void setHouseNo(int houseNo) {
this.houseNo = houseNo;
}
@Override
public String toString() {
return "houseNo : " + houseNo;
}
}
Employee.java
class Employee implements Cloneable {
private String name = null;
private Address address=null;
@Override
public String toString() {
return "name " + this.getName()+ " address : "+ address;
}
public Employee clone() {
Employee emp = null;
try {
emp = (Employee) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println(e);
}
return emp;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
}
Обратите внимание, что в указанных выше классах класс Employee и класс Address объявлены с видимостью по умолчанию. Мы не должны были делать их публичными, хотя могли бы.
Также обратите внимание на то, как метод clone () был написан в классе Employee. Я явно объявил его как открытый метод и вызвал реализацию суперкласса метода clone. Затем я вернул его до объекта Employee, прежде чем вернуться.
Давайте посмотрим код в действии.
public static void main(String[] args) {
Employee emp1 = new Employee();
Address add1= new Address();
add1.setHouseNo(100);
emp1.setName("ryan");
emp1.setAddress(add1);
Employee emp2 = emp1.clone();
emp2.setName("ryan2");
print("emp1 : " + emp1);
print("emp2 : " + emp2);
print("emp1==emp2 "+(emp1==emp2));
}
Если вы выполните следующий код, вы получите следующий вывод
emp1 : name ryan address : houseNo : 100
emp2 : name ryan2 address : houseNo : 100
emp1==emp2 false
Вы можете заменить оператор печати на ваш оператор логгера для запуска кода.
Обратите внимание, что оператор == указывает, что оба объекта создаются независимо в куче. Кроме того, поля компонента Address также были скопированы.
Здесь необходимо отметить одну важную вещь: вам нужно было реализовать интерфейс Cloneable только в классе Employee. Класс Address не должен реализовывать Cloneable, хотя если вы это сделаете, серьезных последствий не будет!
Теперь давайте посмотрим на второй метод
Использование класса BeanUtils.cloneBean ()
Этот метод использует класс BeanUtils, предоставляемый фундаментом apache. Чтобы использовать этот класс, вы должны иметь как минимум следующие jar-файлы в вашем classpath
Викисклада BeanUtils-1.7.0.jar
Викисклад коллекция-3.1.jar
Обще-каротаж 1.0.4.jar
Класс BeanUtils предоставляет нам метод cloneBean, который клонирует все доступные свойства ваших bean-компонентов. Вот код в действии.
Employee2.class
public class Employee2{
private String name = null;
private Address address=null;
@Override
public String toString() {
return "name " + this.getName()+ " address : "+ address;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
}
Обратите внимание на объявление класса Employee2. Мы не реализовали интерфейс Cloneable. Более того, мы сделали класс «публичным». Публикация класса требуется для класса BeanUtils для извлечения данных из Бина. Также обратите внимание, что нам не нужно было писать функцию clone () в этом классе.
Мы можем повторно использовать существующий класс Address из предыдущего примера, поскольку в него не нужно вносить никаких изменений.
Вам нужно импортировать следующую строку в ваш основной класс
import org.apache.commons.beanutils.BeanUtils;
Теперь давайте взглянем на основную функцию.
public static void main(String[] args) throws Exception{
BeanUtils bu = new BeanUtils();
Employee2 emp1 = new Employee2();
Address add1= new Address();
add1.setHouseNo(100);
emp1.setName("ryan");
emp1.setAddress(add1);
Employee2 emp2 = (Employee2)bu.cloneBean(emp1);
emp2.setName("??");
print(emp1);
print(emp2);
print("emp1==emp2 : "+(emp1==emp2));
}
Как вы видите выше, нам не нужно было ничего делать, мы просто вызывали метод cloneBean объекта BeanUtils и передавали его нашему компоненту Employee2. Как и ожидалось, была создана глубокая копия объекта.
Если вы запустите код, вы получите следующий вывод
name ryan address : houseNo : 100
name ?? address : houseNo : 100
emp1==emp2 : false
Как и ожидалось, оба объекта считаются разными объектами в куче. Они просто имеют одинаковые значения для своих свойств.
В описанных выше методах вы можете видеть, что метод BeanUtils можно использовать в гораздо более широкой области, поскольку большинство ваших JavaBeans будут общедоступными, но вы не всегда можете иметь доступ к коду ваших JavaBeans для написания метода клонирования.
Вот и все, ребята!
Удачного программирования ?
От http://mycodefixes.blogspot.com/2011/02/creating-deep-copy-of-javabeans.html