2016-01-06 2 views
-1

Я пытаюсь сделать копию объекта, чтобы выполнить некоторые тесты, не затрагивая оригинальный объект. Я сделал эту функцию copy(), но исходный объект все еще затронут.копия объекта (JAVA)

Внутри класса "I" У меня есть эта функция копирования:

@Override 
public Piece copy() { 
    I newPiece = new I(blocks[0], blocks[1], blocks[2], blocks[3]); 
    newPiece.STATUS = this.STATUS; 
    newPiece.FORM = this.FORM; 
    return newPiece; 
} 

, и я пытаюсь сделать копию, как это:

Piece rotated = piece.copy(); 
rotated.changeForm(); 

класса "I" является подклассом абстрактного класса с абстрактным методом copy(). когда я делаю changeForm() в скопированном объекте, он также влияет на исходный.

решаемых

объектов Block были переданы в качестве ссылки тоже так мне нужно добавить метод копирования() даже для блочного типа. Код изменился следующим образом:

@Override 
public Piece copy() { 
    I newPiece=new I(blocks[0].copy(),blocks[1].copy(),blocks[2].copy(),blocks[3].copy()); 
    newPiece.STATUS=this.STATUS; 
    newPiece.FORM=this.FORM; 
    return newPiece; 
} 
+0

Что тип 'blocks'? – Eran

+0

Я содержание блоков являются ссылочными типами, их также нужно скопировать. – jHilscher

+1

если вы сделаете копию, установив объекты из оригинала в качестве свойств из копии, внесение изменений в те же свойства повлияет на свойства из оригинала и копии – Tom

ответ

2

Также необходимо скопировать каждый тип атрибутов Piece или полей, которые не являются примитивным типом.
Значения STATUS, blocks[1], blocks[2], blocks[3] и FORM.

Надеюсь, это поможет.

2

Если содержимое блоков является ссылочным, вам также придется их скопировать.

В качестве альтернативы вы можете просто создать новый конструктор для Piece и использовать его.

Piece newPiece = new Piece(oldPiece.thing1(), oldPiece.thing2().....); 
2

Это проблема, в конструкторе копирования:

Piece rotated=piece.copy();

Это просто скопировать ссылку на кусок. Оба объекта по-прежнему будут ссылаться на один и тот же объект.

Вы можете использовать:

Piece rotated = new Piece(piece.copy());

2

Вы не изменяя новый объект, вы меняете его содержание. К сожалению, исходный объект имеет то же содержимое, поэтому появляется, как будто вы что-то сделали с исходным объектом.

Вы сделали то, что называется мелкой копии. Казалось бы, вам нужно сделать глубокую копию , которая включает в себя изготовление копий содержимого исходного объекта. В вашем случае, вам нужно сделать копию blocks[0], blocks[1] и т.д.

вопрос, который может преследовать вас, как глубоко , что копия должна быть. Вы, несомненно, узнаете, но вам, возможно, придется идти глубже, чем кажется на первый взгляд.

1

Как отмечают предыдущие авторы, вы должны сделать глубокую копию объекта, но с вашим кодом вы делаете только мелкую копию.

Самый быстрый и простой способ глубокого копирования объекта в java - serialize() it и deserialize().

Предполагая, что все ваши классы реализуют интерфейс java.io.Serializable:

public static <T extends Serializable> T copy(T orig) { 

    T obj = null; 
    try { 
     // Write the object out to a byte array 
     ByteArrayOutputStream bos = new ByteArrayOutputStream(); 
     ObjectOutputStream out = new ObjectOutputStream(bos); 
     out.writeObject(orig); 
     out.flush(); 
     out.close(); 

     // Make an input stream from the byte array and read 
     // a copy of the object back in. 
     ObjectInputStream in = new ObjectInputStream(
       new ByteArrayInputStream(bos.toByteArray())); 
     obj = (T) in.readObject(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } catch (ClassNotFoundException cnfe) { 
     cnfe.printStackTrace(); 
    } 
    return obj; 
} 
Смежные вопросы