If you don't clone in Java then what do you do

2019-04-20 02:14发布

Does anyone have any suggested or established best practices and naming conventions for copy constructors / factory methods etc in Java? In particular, say I have a class Thing and I want a method somewhere that returns a new Thing with the same value as a Thing passed in (or as the instance if it's an instance method). Would you have this as constructor or a static factory method or instance method? What would you call it?

As per the title, I want to avoid clone() and Cloneable.

标签: java oop
8条回答
\"骚年 ilove
2楼-- · 2019-04-20 02:36

This is not the nicest approach to copying objects but the following is sometimes useful if you wish to perform a deep copy of a Serializable object. This avoids having to write copy constuctors, implement Cloneable or writing factory classes.

ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(bos);

//Serializes the input object
oos.writeObject(input);

ByteArrayInputStream bais = new ByteArrayInputStream(bos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);

//Copy of the input object
Object output = ois.readObject();

Don't forget to handle the exceptions and to close the streams nicely.

查看更多
爷的心禁止访问
3楼-- · 2019-04-20 02:45

I'd do a constructor

...
public Thing(Thing copyFrom)
{
    attr1 = copyFrom.attr1;
    attr2 = copyFrom.attr2;
    //etc...
}

then when you want to clone it

Thing copy = new Thing(copy from me);
查看更多
聊天终结者
4楼-- · 2019-04-20 02:50

Use immutable data structures. The only reason you feel that you need clone() is that you're mutating your objects in place. Stop doing that. Think about how you can:

  • Make your classes final.
  • Make fields in your classes final and private.

For example, here's a "setter" for an immutable 3D vector object:

public Vector3D setX(double x) {
  return new Vector3D(x, this.y, this.z);
}

So I guess what I'm saying is... I use copy constructors instead of mutation, and I just name them according to the attribute that I want to modify.

查看更多
淡お忘
5楼-- · 2019-04-20 02:54

You can overwrite the clone()-method, if you want. Another used practice is a constructor, that takes an object of this type, i.e. new ArrayList(anotherList).

查看更多
我欲成王,谁敢阻挡
6楼-- · 2019-04-20 02:58

Effective Java recommends either of the following:

  1. A copy constructor (as noted by others):

    public Item(Item item)

  2. A copy factory method:

    public static Item newInstance(Item item)

(Also, no copying for immutables)

The primary difference is that with #1 you choose the actual class of the result, and with #2 the implementer can return a subclass. The semantics of the class may guide you into which one is best.

查看更多
beautiful°
7楼-- · 2019-04-20 02:59

You've got a few options, implement Cloneable, add a copy constructor but my preferred way is to use a method (static or instance) that has a name which is descriptive of what the copy operation is doing - is it a deep or shallow copy, etc.

查看更多
登录 后发表回答