Различные методы копирования сущностей Java и практический бой
Различные методы копирования сущностей Java и практический бой

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).

преимущество

  1. Простота:использовать BeanUtils.copyProperties Методы позволяют значительно упростить код, избегая необходимости вручную писать для каждого свойства. get и set Громоздкий процесс звонка.
  2. гибкость:Он не требует исходного объектаи Целевой объект имеет тот же класс,Если они имеют одинаковое имя и свойства совместимых типов.,Вы можете копировать атрибуты.
  3. механизм отражения:Методпроходить Java механизм отражениявыполнить,Таким образом, объекты могут обрабатываться динамически.,Добавлена ​​кодировка гибкости.
  4. Масштабируемость:Apache Commons BeanUtils 库提供了много工具方法,Не ограничивается недвижимостью копировать,Он также включает в себя такие функции, как динамический запрос и настройку атрибутов, а также операции с вложенными атрибутами.

недостаток

  1. Проблемы с производительностью:потому что BeanUtils.copyProperties механизм используется внутри метода отражения, его эффективность сравнивают с прямым get и set Вызовы методов выполняются медленнее. существования В приложениях, чувствительных к производительности, это может стать проблемой.
  2. безопасность типаBeanUtils.copyProperties существовать Копирование атрибутов во время выполнения,Компилятор не проверяет совместимость типов. Если типы атрибутов исходного объекта и целевого объекта не совпадают,Волясуществовать выдает исключение при запуске.
  3. Обработка исключений:использовать反射操作时,Могут быть выброшены исключения, связанные с отражением.,нравиться InvocationTargetExceptionIllegalAccessException и т. д., требуется дополнительная обработка этих исключений.
  4. зависимость:использовать BeanUtils.copyProperties нужно зависеть от Apache Commons BeanUtils библиотека, а это означает, что в проекте необходимо ввести эту внешнюю зависимость.

Взятые вместе,BeanUtils.copyProperties Это очень удобный инструментальный метод, который может снизить нагрузку на кодирование и повысить эффективность разработки. Однако, принимая решение об его использовании, вам необходимо сопоставить удобство, которое оно приносит, с потенциальным влиянием на производительность, особенно при работе с большими объемами данных или в сценариях, чувствительных к производительности. В этих случаях вы можете рассмотреть возможность использования напрямую get/set метод или найдите другие библиотеки копирования атрибутов (например, ModelMapper、MapStruct и т. д.) в качестве альтернативы.

ModelMapper

является мощным и гибким Java Библиотека для отображения объектов. Он автоматически обрабатывает сопоставление различных свойств между объектами, что позволяет разработчикам легко передавать свойства одного объекта другому объекту, даже если имена и типы свойств двух объектов не совсем совпадают. Модель Маппер Благодаря интеллектуальным стратегиям сопоставления потребность в ручном картографировании снижается,тем самым повышая эффективность разработки. Используется следующее ModelMapper 的一些преимуществоискрытыйсуществоватьнедостаток:

преимущество

  1. Уменьшите шаблонный код:Автоматическое сопоставление свойств сокращает объем работы по ручному кодированию.,Например, нет необходимости писать вызов get и set для каждого свойства.
  2. гибкость:ModelMapper Предусмотрены различные варианты конфигурации, в том числе стратегии строгого сопоставления, сопоставление настраиваемых типов, условное сопоставление и т. д. для адаптации к сложным потребностям сопоставления.
  3. безопасность типа:相比использовать反射直接操作属性的库(нравиться Apache Commons BeanUtils),ModelMapper существования обеспечивает большую безопасность при компиляции типа, уменьшая количество ошибок во время выполнения.
  4. Поддержка сложного картографирования:ModelMapper Возможность обработки более сложных сценариев сопоставления, таких как вложенные объекты, сопоставление коллекций и т. д.

недостаток

  1. Накладные расходы на производительность:Хотя ModelMapper Уменьшает необходимость ручного кодирования, но автоматический процесс картирования создаст определенные Накладные данные. расходы на производительность. В приложениях, чувствительных к производительности, это может стать важным фактором.
  2. кривая обучения:Хотя基本использовать较为简单,Но чтобы в полной мере использовать ModelMapper Расширенные функции и параметры конфигурации, разработчикам придется потратить время на их изучение. API и Как использовать.
  3. Стоимость первоначальной настройки:Для некоторых сложных картографических задач,Для обеспечения правильного поведения сопоставления может потребоваться относительно утомительная работа по настройке.

Пример использования

Ниже приведен простой пример использования ModelMapper для копирования объектов:

Сначала добавьте в проект зависимость ModelMapper (в качестве примера возьмем Maven):

xmlКопировать код

Язык кода:javascript
копировать
<dependency>
    <groupId>org.modelmappergroupId>
    <artifactId>modelmapperartifactId>
    <version>2.3.8version>
dependency>

Затем предположим, что есть два класса, один из которых является классом сущностей. User,Другой является объектом передачи UserDTO,可以использовать ModelMapper Воля User Свойства экземпляра UserDTO В примере:

Java-код копирования

Язык кода:javascript
копировать
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 Несколько методов сбора глубоких копий:

1. Через сериализацию и десериализацию

Этот метод требует, чтобы объекты в коллекции и все другие объекты, на которые имеются ссылки внутри объекта, реализовывали Serializable интерфейс.

Java-код копирования

Язык кода:javascript
копировать
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);
        }
    }
}

Этот метод прост, но не особенно эффективен и подходит для коллекций без сложных ссылок или небольших размеров.

2. использовать Сторонние библиотеки

Например, используя Apache Commons Lang предоставил SerializationUtils Класс (необходимо добавить Apache Commons Lang полагаться).

Java-код копирования

Язык кода:javascript
копировать
import org.apache.commons.lang3.SerializationUtils;

// Предположим, что ваш список содержит экземпляры SomeClass.
List original = new ArrayList<>();
List copied = SerializationUtils.clone((Serializable) original);

Этот метод также основан на механизме сериализации и более прост в использовании.

3. Вручную внедрить глубокое копирование

Для этого необходимо, чтобы вы четко знали структуру каждого объекта в коллекции и способы копирования этих объектов.

Java-код копирования

Язык кода:javascript
копировать
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 Должен быть способ реализовать собственную логику глубокого копирования, например конструктор копирования или метод, возвращающий копию объекта.

Какой метод выбрать?

  • Если структура объекта проста и производительность не имеет значения, вы можете выбрать метод сериализации.
  • Если структура объекта сложна или требуется высокопроизводительное копирование, рекомендуется реализовать логику глубокого копирования вручную.
  • Сторонние Метод библиотеки документов — это промежуточный вариант, который прост в использовании, но может быть не таким гибким, как методы, реализуемые вручную.
boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose