Java Копирование объекта обычно относится к процессу копирования значения атрибута одного объекта в другой объект. Физические копии могут быть поверхностными копиями (Shallow Копирование) или глубокое копирование (Deep Копия). Неглубокая копия ссылается только на объект, а не сам объект; глубокая копия копирует объект и все объекты, на которые имеются ссылки внутри объекта; Существует множество способов реализации копирования сущностей, в том числе прямое. задание、Используйте метод клонирования、через сериализацию/десериализацию,а также Используйте отражениеили Сторонние библиотека. Эти принципы реализации подробно представлены ниже:
Самый прямой способ копирования — присвоение вручную, то есть явный вызов метода получения каждого атрибута исходного объекта и установка полученного значения с помощью метода установки целевого объекта. Этот метод прост и интуитивно понятен, но когда атрибутов много или структура объекта сложна, объем кода велик и он подвержен ошибкам.
Java предоставил Cloneable
Интерфейс, класс реализует этот интерфейс и переопределяет его. Object
сорт clone()
Методы, обеспечивающие возможность самовоспроизведения. в соответствии с clone()
Реализация метода различна и может быть поверхностной или глубокой копией. Однако этот метод требует ручной обработки каждого атрибута, что требует глубокого копирования, которое подвержено ошибкам и негибко.
Этот метод обеспечивает полную глубокую копию путем сериализации объекта в поток байтов, а затем десериализации нового объекта из потока байтов. Для этого необходимо, чтобы объект и все объекты, на которые он ссылается, реализовали Serializable
интерфейс. Хотя этот метод позволяет выполнить глубокое копирование за один раз, его производительность относительно низка и требуется обработка исключений, которые могут возникнуть в процессе сериализации.
С помощью механизма отражения Java вы можете динамически получать информацию о классе и информацию об атрибутах объекта во время выполнения, а затем динамически считывать значение атрибута и устанавливать его для другого объекта. Этот метод не требует, чтобы объекты реализовывали определенные интерфейсы или методы, и является более гибким. Однако операции отражения имеют более низкую производительность и требуют решения таких проблем, как безопасность и контроль доступа.
много Сторонние библиотеки,нравиться Apache Commons BeanUtils、Spring BeanUtils、ModelMapper、MapStruct и т. д., предоставляя более продвинутые и гибкие функции копирования. Эти библиотеки обычно используют отражение внутри себя, но предоставляют краткую информацию. API и решает распространенные проблемы, такие как производительность, преобразование типов и глубокое копирование. Использование этих библиотек может значительно снизить нагрузку на ручное программирование и повысить эффективность разработки.
в общем,Принцип реализации копирования сущностей включает в себя прямое присвоение атрибутов, клонирование объектов, сериализацию/десериализацию, отражение и другие технологии. Какой подход вы выберете, зависит от ваших конкретных потребностей, сложности ваших объектов, ваших требований к производительности и вашей готовности вводить внешние зависимости. существуют на практике,Чтобы сбалансировать эффективность разработки и производительность,Разработчики обычно склонны использовать зрелые Сторонние библиотека для получения физической копии.
BeanUtils.copyProperties
Метод — это инструментальный метод, предоставляемый библиотекой Apache Commons BeanUtils, который может копировать свойства одного объекта Java Bean в другой объект Java Bean. Этот метод широко используется, особенно в сценариях, где требуется преобразование данных между объектами, например преобразование сущностей базы данных в передаваемые объекты (DTO).
BeanUtils.copyProperties
Методы позволяют значительно упростить код, избегая необходимости вручную писать для каждого свойства. get и set Громоздкий процесс звонка.BeanUtils.copyProperties
механизм используется внутри метода отражения, его эффективность сравнивают с прямым get и set Вызовы методов выполняются медленнее. существования В приложениях, чувствительных к производительности, это может стать проблемой.BeanUtils.copyProperties
существовать Копирование атрибутов во время выполнения,Компилятор не проверяет совместимость типов. Если типы атрибутов исходного объекта и целевого объекта не совпадают,Волясуществовать выдает исключение при запуске.InvocationTargetException
、IllegalAccessException
и т. д., требуется дополнительная обработка этих исключений.BeanUtils.copyProperties
нужно зависеть от Apache Commons BeanUtils библиотека, а это означает, что в проекте необходимо ввести эту внешнюю зависимость.Взятые вместе,BeanUtils.copyProperties
Это очень удобный инструментальный метод, который может снизить нагрузку на кодирование и повысить эффективность разработки. Однако, принимая решение об его использовании, вам необходимо сопоставить удобство, которое оно приносит, с потенциальным влиянием на производительность, особенно при работе с большими объемами данных или в сценариях, чувствительных к производительности. В этих случаях вы можете рассмотреть возможность использования напрямую get/set метод или найдите другие библиотеки копирования атрибутов (например, ModelMapper、MapStruct и т. д.) в качестве альтернативы.
является мощным и гибким Java Библиотека для отображения объектов. Он автоматически обрабатывает сопоставление различных свойств между объектами, что позволяет разработчикам легко передавать свойства одного объекта другому объекту, даже если имена и типы свойств двух объектов не совсем совпадают. Модель Маппер Благодаря интеллектуальным стратегиям сопоставления потребность в ручном картографировании снижается,тем самым повышая эффективность разработки. Используется следующее ModelMapper 的一些преимуществоискрытыйсуществоватьнедостаток:
Ниже приведен простой пример использования ModelMapper для копирования объектов:
Сначала добавьте в проект зависимость ModelMapper (в качестве примера возьмем Maven):
xmlКопировать код
<dependency>
<groupId>org.modelmappergroupId>
<artifactId>modelmapperartifactId>
<version>2.3.8version>
dependency>
Затем предположим, что есть два класса, один из которых является классом сущностей. User
,Другой является объектом передачи UserDTO
,可以использовать ModelMapper Воля User
Свойства экземпляра UserDTO
В примере:
Java-код копирования
import org.modelmapper.ModelMapper;
public class Main {
public static void main(String[] args) {
ModelMapper modelMapper = new ModelMapper();
User user = new User("John Doe", 30);
UserDTO userDTO = modelMapper.map(user, UserDTO.class);
System.out.println(userDTO.getName() + ", " + userDTO.getAge());
}
}
class User {
private String name;
private int age;
// Constructors, getters and setters
}
class UserDTO {
private String name;
private int age;
// Constructors, getters and setters
}
ModelMapper Это мощный инструмент в области сопоставления объектов, который подходит для многих сценариев, требующих преобразования объектов, особенно при создании приложений с многоуровневой архитектурой (например, MVC ), может эффективно преобразовывать объекты базы данных в DTO или просмотреть модель.
существовать Java Средний, глубокий текст (Deep Копировать) означает не просто копирование ссылки на объект, но и копирование самого объекта и всех объектов внутри него. для List
Для глубокого копирования коллекции нам необходимо обеспечить копирование нового экземпляра каждого объекта в коллекции. Ниже приводится реализация List
Несколько методов сбора глубоких копий:
Этот метод требует, чтобы объекты в коллекции и все другие объекты, на которые имеются ссылки внутри объекта, реализовывали Serializable
интерфейс.
Java-код копирования
import java.io.*;
public class DeepCopy {
@SuppressWarnings("unchecked")
public static List deepCopy(List list) {
try {
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(list);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in = new ObjectInputStream(byteIn);
return (List) in.readObject();
} catch (IOException | ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
}
Этот метод прост, но не особенно эффективен и подходит для коллекций без сложных ссылок или небольших размеров.
Например, используя Apache Commons Lang предоставил SerializationUtils
Класс (необходимо добавить Apache Commons Lang полагаться).
Java-код копирования
import org.apache.commons.lang3.SerializationUtils;
// Предположим, что ваш список содержит экземпляры SomeClass.
List original = new ArrayList<>();
List copied = SerializationUtils.clone((Serializable) original);
Этот метод также основан на механизме сериализации и более прост в использовании.
Для этого необходимо, чтобы вы четко знали структуру каждого объекта в коллекции и способы копирования этих объектов.
Java-код копирования
import java.util.ArrayList;
import java.util.List;
public class ManualDeepCopy {
public static List deepCopy(List originalList) {
List copiedList = new ArrayList<>();
for (SomeClass item : originalList) {
// Предположим, что SomeClass реализовал собственную логику глубокого копирования.
SomeClass copiedItem = item.deepCopy();
copiedList.add(copiedItem);
}
return copiedList;
}
}
существуют В этом примере,SomeClass
Должен быть способ реализовать собственную логику глубокого копирования, например конструктор копирования или метод, возвращающий копию объекта.