search
HomeJavajavaTutorialDetailed explanation of java copy mechanism


In Java, copying is divided into two types: deep copy and shallow copy. Java implements a method called clone in the public superclass Object. The new object cloned by this method is a shallow copy, and the clone method defined by yourself is a deep copy.

(1) Clone method in Object

If we new a new object, use a statement to reference it, and then use another statement to reference the previous one declaration, then the final result is: the two declared variables will point to the same object, and if one place is changed, both will be changed. If we want to create a copy of an object that is exactly the same as the various properties of the object, and modifying the copy has nothing to do with the original object, then we need to use the clone method at this time.

package Clone;import java.util.Date;/**
 * 
 * @author QuinnNorris 
 * java中的两种拷贝机制
 */public class Clone {

    /**
     * @param args
     * @throws CloneNotSupportedException 
     */
    public static void main(String[] args) throws CloneNotSupportedException {        
    // TODO Auto-generated method stub

        ClassA valA = new ClassA(1, "old", new Date());        
        // 声明一个新的ClassA对象,我们不需要太关注ClassA的功能
        ClassA valB = valA;        
        // 将valA引用的对象赋给valB
        valA.setObject("new");        
        // 更改valA中的值,此时valB也被更改了,因为valA和valB指向同一个对象

        valB = valA.clone();//通过clone方法制造副本
    }
}

The overriding part of the clone method in the ClassA class:

//需要实现Cloneable接口public class ClassA implements Cloneable {

    public ClassA clone() throws CloneNotSupportedException {        
    return (ClassA) super.clone();
    //调用父类(Object)的clone方法
    }

}

1. How to use the clone method in Object

Someone summarized the use of clone Let’s share the four rules of methods:

  1. In order to obtain a copy of the object, we can use the clone() method of the Object class.

  2. Override the clone() method of the base class in the derived class and declare it as public.

  3. In the clone() method of the derived class, call super.clone().

  4. Implement the Cloneable interface in the derived class.

2. protected modified clone method

In java.lang.Object, he sets the clone method to protected Modification, this is a very special situation. The scope of protected is: package visible + inheritable. The reason for this setting is because this method returns a cloned object. That is, the type of clone method is unknown. There is no way to determine the type of the return value. Naturally, future generations can only implement it and rewrite it. , in order to allow descendants to inherit without being too open, it is set to a protected type.

3. To implement the clone method, you need to implement the Cloneable interface

So why should we implement the Cloneable interface when we rewrite the clone method? In fact, the Cloneable interface is a marked interface in Java. Marked interfaces refer to interfaces without methods and attributes. They exist only to let everyone know some information, and they can be judged when using: xxx instanceof Cloneable. The emergence of the Cloneable interface is to let designers know that cloning is required. If an object needs to be cloned but does not implement (actually, "implementation" here is replaced by "write" is more accurate) the Cloneable interface, a checked exception will be generated.

4. To implement the clone method, you need to call the clone of the parent class

In order to copy an object that is exactly the same as the object that calls the method, we need to use the parent class The clone method of a class, and so on for the parent class, until the clone method of Object is reached, then what is the use of the clone method of Object? This is what the API says:

protected Object clone( ) throws CloneNotSupportedException
Creates and returns a copy of this object.
The precise meaning of "copy" may depend on the object's class. The purpose of this is that, for any object x,
Expression: x.clone() != x is true,
Expression: x.clone().getClass() == x.getClass() is also true,
But these are not requirements that must be met.
Under normal circumstances:
x.clone().equals(x) is true, but this is not a requirement that must be met.
By convention, the returned object should be obtained by calling super.clone.
If a class and all its superclasses (except Object) comply with this convention, then x.clone().getClass() == x.getClass().

The above is a basic explanation of clone in the API. What we can conclude is that as long as spuer.clone() is called properly, it will return a cloned object. At runtime, clone() in Object identifies which object you want to copy, then allocates space for this object, copies the object, and copies the contents of the original object one by one to the storage space of the new object. In this cloned object, all attributes are the same as those of the cloned object, and these same attributes are divided into two types:

The first type: eight primitive types and immutable objects (such as String)
The second type: other class objects

For the first type, the clone method sets their values ​​to the values ​​of the original objects without any problems. For the second type, the clone method simply points the reference of the copied new object to the reference pointed by the original object. The second type of class object will be modified by the two objects. So this time it involves the concept of deep and shallow copies.

(2) Shallow copy

Shallow copy: All variables of the copied object contain the same values ​​as the original object, and all references to other objects Still points to the original object. In other words, a shallow copy only copies the object in question, not the objects it refers to.

比如举个例子,一个类A中有另外一个类B类型的变量。在A重写clone函数调用super.clone的时候,创建的新对象和原来对象中的类B类型的变量是同一个,他们指向了同一个B的类型变量。如果在A中对B的变量做了修改,在新的拷贝出来的对象中B的变量也会被同样的修改。

请记住,直接调用super.clone实现的clone方法全部都是浅拷贝。

(三)深拷贝

深拷贝:被拷贝对象的所有变量都含有与原来的对象相同的值,除去那些引用其他对象的变量。那些引用其他对象的变量将指向被复制过的新对象,而不再是原有的那些被引用的对象。换言之,深复制把要复制的对象所引用的对象都复制了一遍。

通俗的说,如果说浅拷贝,开始的时候是两条线,如果在最后有一个其他类的变量,那么这两条线最后会合二为一,共同指向这变量,都能对他进行操作。深拷贝则是完完全全的两条线,互不干涉,因为他已经把所有的内部中的变量的对象全都复制一遍了。

深拷贝在代码中,需要在clone方法中多书写调用这个类中其他类的变量的clone函数。

(四)串行化深拷贝

在框架中,有的时候我们发现其中并没有重写clone方法,那么我们在需要拷贝一个对象的时候是如何去操作的呢?答案是我们经常会使用串行化方法,实现Serializable接口。

去寻找其他的方法来替代深拷贝也是无可奈何的事情,如果采用传统的深拷贝,难道你拷贝一个对象的时候向其中追无数层来拷贝完所有的对象变量么?先不谈这么做的时间消耗,仅仅是写这样的代码都会让人望而生畏。串行化深拷贝就是这样一个相对简单的方法。

把对象写到流里的过程是串行化(Serilization)过程,但是在Java程序师圈子里又非常形象地称为“冷冻”或者“腌咸菜(picking)”过程;而把对象从流中读出来的并行化(Deserialization)过程则叫做 “解冻”或者“回鲜(depicking)”过程。应当指出的是,写在流里的是对象的一个拷贝,而原对象仍然存在于JVM里面,因此“腌成咸菜”的只是对象的一个拷贝,Java咸菜还可以回鲜。

上面是网上的专业解释,我也不在这里班门弄斧了。在Java语言里深复制一个对象,常常可以先使对象实现Serializable接口,然后把对象(实际上只是对象的一个拷贝)写到一个流里(腌成咸菜),再从流里读出来(把咸菜回鲜),便可以重建对象。

public Object deepClone() 
{ 
 //写入对象 
 ByteArrayOutoutStream bo=new ByteArrayOutputStream(); 
 ObjectOutputStream oo=new ObjectOutputStream(bo); 
 oo.writeObject(this); 
 //读取对象
 ByteArrayInputStream bi=new ByteArrayInputStream(bo.toByteArray()); 
 ObjectInputStream oi=new ObjectInputStream(bi); 
 return(oi.readObject()); 
}

虽然这种学院派的代码看起来很复杂,其实只是把对象放到流里,再拿出来。相比较分析判断无数的clone,这样简直是再简单不过了。这样做的前提是对象以及对象内部所有引用到的对象都是可串行化的,否则,就需要仔细考察那些不可串行化的对象是否设成transient。

transient:一个对象只要实现了Serilizable接口,这个对象就可以被序列化(序列化是指将java代码以字节序列的形式写出,即我们上面代码前三行写入对象),Java的这种序列化模式为开发者提供了很多便利,可以不必关系具体序列化的过程,只要这个类实现了Serilizable接口,这个的所有属性和方法都会自动序列化。但是有种情况是有些属性是不需要序列号的,所以就用到这个关键字。只需要实现Serilizable接口,将不需要序列化的属性前添加关键字transient,序列化对象的时候,这个属性就不会序列化到指定的目的地中。

(五)总结

在实际的应用中,深拷贝和浅拷贝只是两个概念,不一定谁比谁好,要按照实际的工作来确定如何去拷贝一个对象。如果在数据库操作方面,为了取出一张表时不涉及其他的表,肯定需要使用浅拷贝,而在框架的Serializable中,虽然耗时,但是深拷贝是非常有必要的。

在java中,拷贝分为深拷贝和浅拷贝两种。java在公共超类Object中实现了一种叫做clone的方法,这种方法clone出来的新对象为浅拷贝,而通过自己定义的clone方法为深拷贝。

 以上就是java拷贝机制详解的内容,更多相关内容请关注PHP中文网(www.php.cn)!


Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
How does the class loader subsystem in the JVM contribute to platform independence?How does the class loader subsystem in the JVM contribute to platform independence?Apr 23, 2025 am 12:14 AM

The class loader ensures the consistency and compatibility of Java programs on different platforms through unified class file format, dynamic loading, parent delegation model and platform-independent bytecode, and achieves platform independence.

Does the Java compiler produce platform-specific code? Explain.Does the Java compiler produce platform-specific code? Explain.Apr 23, 2025 am 12:09 AM

The code generated by the Java compiler is platform-independent, but the code that is ultimately executed is platform-specific. 1. Java source code is compiled into platform-independent bytecode. 2. The JVM converts bytecode into machine code for a specific platform, ensuring cross-platform operation but performance may be different.

How does the JVM handle multithreading on different operating systems?How does the JVM handle multithreading on different operating systems?Apr 23, 2025 am 12:07 AM

Multithreading is important in modern programming because it can improve program responsiveness and resource utilization and handle complex concurrent tasks. JVM ensures the consistency and efficiency of multithreads on different operating systems through thread mapping, scheduling mechanism and synchronization lock mechanism.

What does 'platform independence' mean in the context of Java?What does 'platform independence' mean in the context of Java?Apr 23, 2025 am 12:05 AM

Java's platform independence means that the code written can run on any platform with JVM installed without modification. 1) Java source code is compiled into bytecode, 2) Bytecode is interpreted and executed by the JVM, 3) The JVM provides memory management and garbage collection functions to ensure that the program runs on different operating systems.

Can Java applications still encounter platform-specific bugs or issues?Can Java applications still encounter platform-specific bugs or issues?Apr 23, 2025 am 12:03 AM

Javaapplicationscanindeedencounterplatform-specificissuesdespitetheJVM'sabstraction.Reasonsinclude:1)Nativecodeandlibraries,2)Operatingsystemdifferences,3)JVMimplementationvariations,and4)Hardwaredependencies.Tomitigatethese,developersshould:1)Conduc

How does cloud computing impact the importance of Java's platform independence?How does cloud computing impact the importance of Java's platform independence?Apr 22, 2025 pm 07:05 PM

Cloud computing significantly improves Java's platform independence. 1) Java code is compiled into bytecode and executed by the JVM on different operating systems to ensure cross-platform operation. 2) Use Docker and Kubernetes to deploy Java applications to improve portability and scalability.

What role has Java's platform independence played in its widespread adoption?What role has Java's platform independence played in its widespread adoption?Apr 22, 2025 pm 06:53 PM

Java'splatformindependenceallowsdeveloperstowritecodeonceandrunitonanydeviceorOSwithaJVM.Thisisachievedthroughcompilingtobytecode,whichtheJVMinterpretsorcompilesatruntime.ThisfeaturehassignificantlyboostedJava'sadoptionduetocross-platformdeployment,s

How do containerization technologies (like Docker) affect the importance of Java's platform independence?How do containerization technologies (like Docker) affect the importance of Java's platform independence?Apr 22, 2025 pm 06:49 PM

Containerization technologies such as Docker enhance rather than replace Java's platform independence. 1) Ensure consistency across environments, 2) Manage dependencies, including specific JVM versions, 3) Simplify the deployment process to make Java applications more adaptable and manageable.

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Safe Exam Browser

Safe Exam Browser

Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

EditPlus Chinese cracked version

EditPlus Chinese cracked version

Small size, syntax highlighting, does not support code prompt function

SecLists

SecLists

SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.