Java [Version de base] SerializationUtils#Clone copie superficielle, copie profonde

Introduction : Aujourd'hui, au travail, des collègues ont utilisé la fonction Java8 Lists.partition pour mettre à jour/interroger des données par lots. L'équipe d'architecture a étendu la méthode mybatis#Interceptor dans le plug-in mybatis pour implémenter l'interception. Il existe une grande quantité d'informations sur le Internet qui peut être interrogé. Je ne le présenterai pas ici. La connexion Utiliser la méthode SerializationUtils.clone((Serializing) originParameter); dans le processeur pour sérialiser l'objet param. Lorsque l'objet est copié, la liste obtenue après Lists.partition est un objet Partition, qui hérite de AbstractList pour terminer la segmentation de la liste.

Jetons un coup d'œil au code source de Lists.partition :

 public static <T> List<List<T>> partition(List<T> list, int size) {
    
    
        Preconditions.checkNotNull(list);
        Preconditions.checkArgument(size > 0);
        return (List)(list instanceof RandomAccess ? new Lists.RandomAccessPartition(list, size) : new Lists.Partition(list, size));
    }
 private static class Partition<T> extends AbstractList<List<T>> {
    
    
        final List<T> list;
        final int size;

        Partition(List<T> list, int size) {
    
    
            this.list = list;
            this.size = size;
        }

        public List<T> get(int index) {
    
    
            Preconditions.checkElementIndex(index, this.size());
            int start = index * this.size;
            int end = Math.min(start + this.size, this.list.size());
            return this.list.subList(start, end);
        }

        public int size() {
    
    
            return IntMath.divide(this.list.size(), this.size, RoundingMode.CEILING);
        }

        public boolean isEmpty() {
    
    
            return this.list.isEmpty();
        }
    }

Examinez l'objet Liste de partitions. Il appartient à une classe interne et n'implémente pas l'interface Serialisable, ce qui entraîne l'échec du numéro de série.
Message d'erreur :

Caused by: org.apache.commons.lang3.SerializationException: java.io.NotSerializableException: java.util.ArrayList$SubList
	at org.apache.commons.lang3.SerializationUtils.serialize(SerializationUtils.java:273) ~[commons-lang3-3.12.0.jar:3.12.0]
	at org.apache.commons.lang3.SerializationUtils.serialize(SerializationUtils.java:248) ~[commons-lang3-3.12.0.jar:3.12.0]
	at org.apache.commons.lang3.SerializationUtils.clone(SerializationUtils.java:138) ~[commons-lang3-3.12.0.jar:3.12.0]
	at com.txxy.cloud.starter.druid.interceptor.CipherInterceptor.intercept(CipherInterceptor.java:92) ~[txxy-cloud-starter-druid-1.8.0-SNAPSHOT.jar:1.8.0-SNAPSHOT]
	at org.apache.ibatis.plugin.Plugin.invoke(Plugin.java:61) ~[mybatis-3.5.5.jar:3.5.5]
	at com.sun.proxy.$Proxy466.update(Unknown Source) ~[?:?]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.update(DefaultSqlSession.java:197) ~[mybatis-3.5.5.jar:3.5.5]
	at org.apache.ibatis.session.defaults.DefaultSqlSession.insert(DefaultSqlSession.java:184) ~[mybatis-3.5.5.jar:3.5.5]
	at sun.reflect.GeneratedMethodAccessor1471.invoke(Unknown Source) ~[?:?]
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:1.8.0_212]
	at java.lang.reflect.Method.invoke(Method.java:498) ~[?:1.8.0_212]
	at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:426) ~[mybatis-spring-2.0.5.jar:2.0.5]

texte:

Copie superficielle

Copie superficielle : toutes les propriétés de membre de l'objet copié ont les mêmes valeurs que l'objet d'origine et toutes les références à d'autres objets pointent toujours vers l'objet d'origine.

En d’autres termes, une copie superficielle copie uniquement l’objet considéré (propriétés de l’objet, données), et non l’objet auquel il fait référence (adresse de l’objet).

copie approfondie

Copie profonde : toutes les variables de l'objet copié contiennent les mêmes valeurs que l'objet d'origine, à l'exception des variables qui font référence à d'autres objets. Les variables qui font référence à d'autres objets pointeront vers le nouvel objet copié, et non vers les objets référencés d'origine.

En d’autres termes, la copie profonde copie tous les objets (propriétés de l’objet, données) référencés par l’objet à copier.

2. La copie profonde est relativement simple à mettre en œuvre, il suffit de cloner à nouveau l'objet dans l'objet :

commons-lang-2.6.jar

例如:Object obj = SerializationUtils.clone( objectFrom )

Code source:

   /**
     * <p>Deep clone an {@code Object} using serialization.</p>
     *
     * <p>This is many times slower than writing clone methods by hand
     * on all objects in your object graph. However, for complex object
     * graphs, or for those that don't support deep cloning this can
     * be a simple alternative implementation. Of course all the objects
     * must be {@code Serializable}.</p>
     *
     * @param <T> the type of the object involved
     * @param object  the {@code Serializable} object to clone
     * @return the cloned object
     * @throws SerializationException (runtime) if the serialization fails
     */
    public static <T extends Serializable> T clone(final T object) {
    
    
        if (object == null) {
    
    
            return null;
        }
        final byte[] objectData = serialize(object);
        final ByteArrayInputStream bais = new ByteArrayInputStream(objectData);

        try (ClassLoaderAwareObjectInputStream in = new ClassLoaderAwareObjectInputStream(bais,
                object.getClass().getClassLoader())) {
    
    
            /*
             * when we serialize and deserialize an object,
             * it is reasonable to assume the deserialized object
             * is of the same type as the original serialized object
             */
            @SuppressWarnings("unchecked") // see above
            final T readObject = (T) in.readObject();
            return readObject;

        } catch (final ClassNotFoundException ex) {
    
    
            throw new SerializationException("ClassNotFoundException while reading cloned object data", ex);
        } catch (final IOException ex) {
    
    
            throw new SerializationException("IOException while reading or closing cloned object data", ex);
        }
    }

Les notes sont introduites ici~~

Je suppose que tu aimes

Origine blog.csdn.net/weixin_43829047/article/details/129387832
conseillé
Classement