Java zero foundation entry series – day14 cloning of Java objects

Today we will introduce a concept, object cloning. This article is difficult. Please be prepared first. If you don't understand, you can read it twice. If you still don't understand, you can leave a message below. I will modify and supplement it according to the situation.

Cloning, of course, is to reproduce an object. Why use cloning? When do I need to use it? Let's look at a little chestnut first:

For simplicity, we use a simple version of the goods class here.

   Goods(String aTitle,== setPrice(.price =.title ="Title:"+title+" Price:"+

Then let's use this class.

 GoodsTest {static  main(String[] args){
        Goods goodsA = new Goods("GoodsA",20);
        Goods goodsB = goodsA;
        System.out.println("Before Change:");
        goodsA.print();
        goodsB.print();

        goodsB.setTitle("GoodsB");
        goodsB.setPrice(50);
        System.out.println("After Change:");
        goodsA.print();
        goodsB.print();
    }
}

We create a Goods object to assign to the variable goodsA, then create a Goods variable, assign goodsA to it, first call the print method of Goods to output the information in these two variables, then call setTitle and setPrice methods in the Goods class to modify the object contents in goodsB, and then output the information in two variables, and the following is output:

Before Change:
Title:GoodsA Price:20.0Title:GoodsA Price:20.0After Change:
Title:GoodsB Price:50.0Title:GoodsB Price:50.0

Here we found a supernatural thing. We clearly modified the content of goodsb, but the content of goodsa has also changed. Why on earth? Don't worry and listen to me slowly.

In the Java language, Data types are divided into value types (basic data type) and reference type. The value type includes simple data types such as int, double, byte, Boolean and char, and the reference type includes complex types such as class, interface and array. The value is transferred by using the equal sign assignment. For example, if an integer variable is assigned to another integer variable, the latter will store the value of the former, that is, the integer value in the variable , there is no problem with basic types such as int, double, char, etc., but for objects, it is another matter. Goodsa and goodsb here are variables of goods class objects, but they do not store the content of goods class objects, but store their addresses, which is equivalent to pointers in C + +. If you don't know about pointers, I'll give you another example. We mentioned a chestnut before, comparing the computer to a warehouse administrator and the memory to a warehouse. If you want to use what type of variables, you need to register first, and then the administrator will give you things, but what if you are assigned a house? At this time, instead of moving the house to the register, we register the address of the house. The address here is the content recorded in our class object variable. Therefore, when we assign a class object variable to another class object variable, such as goodsb = goodsa, we actually assign the object address pointed to by a to B, so that B also points to this address, So at this time, goodsa and goodsb operate on the same object.

Therefore, if it is only a simple assignment, the subsequent operations on goodsa and goodsb will affect the same object, which is obviously not our intention. You may also ask, it's not good to directly new another object. Indeed, sometimes, if we need to save a copy of goodsa, we need not only new an object, but also a series of assignment operations to set our new object to be the same as goodsa object. Moreover, the more complex the goods class is, the more cumbersome the operation will be, In addition, the clone method is also used for local optimization, which will be much faster in efficiency. In a word, it is simple and rough.

How do you use cloning? Here we will introduce our awesome object class. All classes are subclasses of object class. Although we do not explicitly declare inheritance relationship, all classes can not escape its clutches. It has two protected methods, one of which is the clone method.

Let me show you the correct operation:

 Goods = = (Goods)

In fact, there are only two modifications. One is that the clonable interface is implemented when defining classes. The knowledge about the interface will be described in detail later. Here, we just need to simply understand it as a specification, and then we overload the clone method, And called the parent class inside, that is (object). We can see that instead of creating a new object, we use the clone method of the parent class to clone it. We won't introduce too much about the knowledge of try catch here, and an article will explain it in detail later. Here we just need to understand that there is a code that may cause errors in the try statement block, and catch will catch and handle such errors.

Next, we will use the cloning method of this class:

 (Goods)goodsA.clone();
        System.out.println("Before Change:");
        goodsA.print();
        goodsB.print();
    }
}

We just changed the assignment to call the clone method of goodsa and perform type conversion. The output is as follows:

After Change:
Title:GoodsA Price:20.0Title:GoodsB Price:50.0

Look, isn't this our goal? Isn't it simple?

But don't be happy too early. There is still something to introduce about cloning.

Cloning can be divided into shallow cloning and deep cloning. We only use shallow cloning above. What's the difference between the two? Here is another example of chestnut, which uses the simplified cart class:

class Cart 实例域Goods goodsList = new Goods("",0);简单起见,这里只放了一个商品double budget = 0.0;预算构造函数public Cart( aBudget){
        budget = aBudget;
    }获取预算 getBudget() { budget;
    }修改预算void setBudget( aBudget) {
        budget =这里只是简单的将商品进行了赋值 addGoods(Goods goods){
        goodsList = (Goods) goods.clone();
    }这是为了演示加上的代码,仅仅将商品标题修改成新标题 changeGoodsTitle(String title){
        goodsList.setTitle(title);
    }打印商品信息 print(){
        System.out.print("Cart内的预算信息:"+budget+" 商品信息:");
        goodsList.print();
    }重载clone方法 Object clone(){
        Cart c = ;{
            c = (Cart) (CloneNotSupportedException e ){
            e.printStackTrace();
        } c;
    }
}

Here, goodslist is changed from an array to a single object variable, which is only used for demonstration convenience. A changegoodtitle method is also added to modify the title of the commodity to another title. Next, modify the goodtest class:

=  Cart(5000="Before Change:""NewTitle""After Change:"

Output information:

Before Change:
Cart内的预算信息:5000.0 商品信息:Title:GoodsA Price:20.0Cart内的预算信息:5000.0 商品信息:Title:GoodsA Price:20.0After Change:
Cart内的预算信息:5000.0 商品信息:Title:NewTitle Price:20.0Cart内的预算信息:5000.0 商品信息:Title:NewTitle Price:20.0

We found that although we call the method in Carta to modify the commodity information in cart a, the information in cart B is also modified. This is because when using the shallow cloning mode, if the member variable is a complex type such as an object, only the value copy is used, just as we introduced earlier. Therefore, although cartb is a copy of Carta, However, their member variable goodslist shares the same object, which is obviously not the effect we want. At this time, we need to use deep copy. Just modify the clone method of cart class:

.clone();
            c.goodsList = (Goods) goodsList.clone();//仅仅添加了这段代码,将商品对象也进行了克隆
        } c;
    }

Now run again:

Cart内的预算信息:5000.0 商品信息:Title:GoodsA Price:20.0

So we get the result we want.

This completes the copy of the object.

Are you?

Hahaha, don't crash. No, there is a more complicated situation, that is, when your member variable also contains reference types, for example, there is a member variable of cartb in cart class, and there are also member variables of reference types in cartb class. At this time, there is a problem of multi-layer cloning. Here is another operation. You only need to understand it, that is, serializing objects. The operation is as follows:

 java.io.* Object deepClone() 
      ByteArrayOutputStream bo = null;
      ObjectOutputStream oo = null;
      ObjectInputStream oi = null;
      ByteArrayInputStream bi = null;
      try{
        bo = =     bi = =

I won't introduce this method more. You just need to know that there is such a method. If you need to use this method in the future, you will know how to deal with it.

To sum up, object cloning is to re copy the current state of an object to another new object. The two object variables point to different objects. Shallow cloning only calls super The clone () method is only a simple copy of the value of the member variable, so when there are complex types such as arrays and objects in the member variable, there will be a tangled relationship. The deep copy does not just call super Clone () method copies the object and copies the complex types in the object, so that the two objects have no relationship and the well water does not interfere with the river.

So far, the cloning of objects is really over. Welcome to continue your attention! If you have any questions you don't understand, you can leave a message. You are also welcome to criticize and correct. If you like my tutorial, remember to use your little hand to click on the recommendation. You are also welcome to pay attention to my blog.

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>