48

I want to make a copy of an object, then after some logic, re-assign the original object the value of the copy.

example:

User userCopy = //make a copy

foreach(...)
{
  user.Age = 1;
  user.ID = -1;

  UserDao.Update(user)


  user = userCopy; 

}

I don't want a copy by reference, it has to be a copy by value.

The above is just a sample, not how I really want to use it but I need to learn how to copy by value.

Blankman
  • 259,732
  • 324
  • 769
  • 1,199

7 Answers7

39

Here are the few techniques I've heard of:

  1. Use clone() if the class implements Cloneable. This API is a bit flawed in java and I never quite understood why clone is not defined in the interface, but in Object. Still, it might work.

  2. Create a clone manually. If there is a constructor that accepts all parameters, it might be simple, e.g new User( user.ID, user.Age, ... ). You might even want a constructor that takes a User: new User( anotherUser ).

  3. Implement something to copy from/to a user. Instead of using a constructor, the class may have a method copy( User ). You can then first snapshot the object backupUser.copy( user ) and then restore it user.copy( backupUser ). You might have a variant with methods named backup/restore/snapshot.

  4. Use the state pattern.

  5. Use serialization. If your object is a graph, it might be easier to serialize/deserialize it to get a clone.

That all depends on the use case. Go for the simplest.

EDIT

I also recommend to have a look at these questions:

Community
  • 1
  • 1
ewernli
  • 38,045
  • 5
  • 92
  • 123
14

You may use clone() which works well if your object has immutable objects and/or primitives, but it may be a little problematic when you don't have these ( such as collections ) for which you may need to perform a deep clone.

User userCopy = (User) user.clone();//make a copy

for(...) {
    user.age = 1;
    user.id = -1;

    UserDao.update(user)
    user = userCopy; 
}

It seems like you just want to preserve the attributes: age and id which are of type int so, why don't you give it a try and see if it works.

For more complex scenarios you could create a "copy" method:

publc class User { 
    public static User copy( User other ) {
         User newUser = new User();
         newUser.age = other.age;
         newUser.id = other.id;
         //... etc. 
         return newUser;
    }
}

It should take you about 10 minutes.

And then you can use that instead:

     User userCopy = User.copy( user ); //make a copy
     // etc. 

To read more about clone read this chapter in Joshua Bloch "Effective Java: Override clone judiciously"

Amir Keshavarz
  • 2,403
  • 3
  • 19
  • 19
OscarRyz
  • 196,001
  • 113
  • 385
  • 569
4

I believe .clone() is what you're looking for, so long as the class supports it.

JC Ford
  • 6,946
  • 3
  • 25
  • 34
3

I know this is a little bit too late but it might just help someone.

In my case I already had a method to make the Object from a json Object and make json from the object. with this you can simply create a new instance of the object and use it to restore. For instance in a function parsing a final object

public void update(final Object object){ 
  final Object original = Object.makeFromJSON(object.toJSON()); 
  // the original is not affected by changes made to object 
}
henriquedn
  • 53
  • 7
2

Can't you just make a copy constructor? By the way Java always passes references by value, so you keep pointing to the same object.

Petar Minchev
  • 46,889
  • 11
  • 103
  • 119
1

You need to do a deep copy from user to usercopy, and then after your login you can reassign your userCopy reference to user.

User userCopy = new User();
userCopy.Age = user.Age
userCopy.ID = user.ID

foreach(...) 
{ 
  user.Age = 1; 
  user.ID = -1; 

  UserDao.Update(user)     

  user = userCopy;       
}
dtb
  • 213,145
  • 36
  • 401
  • 431
KhanS
  • 1,167
  • 2
  • 12
  • 27
0

what language is this? If you're using a language that passes everything by reference like Java (except for native types), typically you can call .clone() method. The .clone() method is typically implemented by copying/cloning all relevant instance fields into the new object.

Lie Ryan
  • 62,238
  • 13
  • 100
  • 144