• Post Reply Bookmark Topic Watch Topic
  • New Topic

Same old question about clone(). How ???  RSS feed

 
Yaroslav Chinskiy
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
All.

I have a delema , I want to create an immutable message. It is not strictly immutable, I just want to create a copy of a message before sending it.
The code looks similar to this:



But clone is protected so the code will not compile. Do you have any advice on how to clone properly?
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Make it completely immutable?Then you don't need to clone it.

Or change the body to a String, which is already immutable, so there is no need for the cloning of the body?
 
Rob Spoor
Sheriff
Posts: 21133
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:Make it completely immutable?Then you don't need to clone it.

That just shifts the problem, since body.clone() is still not accessible.
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Since you know (as a programmer) that the T implements Cloneable, and therefore has a public clone(), then you could use reflection:


Note however, that regardless of the Generic nature or not, the body variable can not be a final field - since you will be unable to assign to the message.body field. If you need the body to be final, you are better off using a Copy Constructor for the Message - rather than clone().
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I take your points. A copy constructor would be better.
 
Yaroslav Chinskiy
Ranch Hand
Posts: 147
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve,

Good catch about final. I will fix it.
I wanted to use reflection as the last reserve. You code will accomplish what I need, but I was hoping for an easier solution. I guess who ever designed clone() did not intend it to be used outside of inheritance. sad.... :banghead:
 
Steve Luke
Bartender
Posts: 4181
22
IntelliJ IDE Java Python
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Yaroslav,

If you wanted to treat your object more like an immutable object, you should probably protect the body a little bit better (for example, copying it on its way into the Message through the constructor, and copying it on its way out of the getBody method) to protect it from being changed by external sources. Example:

 
Rob Spoor
Sheriff
Posts: 21133
87
Chrome Eclipse IDE Java Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Steve Luke wrote:Since you know (as a programmer) that the T implements Cloneable, and therefore has a public clone()

No you don't. The chances are high that clone() will be public, but it's perfectly legal to implement Cloneable and keep clone() protected, or not even overwrite it at all.

Also, the contract for clone() does not require it to return an object of the same class. The returned object can even be unequal to the source. It is in fact very, very loose in what a programmer should do when overriding it. Of course most programmers use super.clone() in the entire chain, but it's not required to do so.

Yaroslav Chinskiy wrote:I guess who ever designed clone() did not intend it to be used outside of inheritance. sad.... :banghead:

A lot of people think the bigger problem is in Cloneable - they think it should enforce clone() to become public. I don't know; yes it would be useful because you could check for Cloneable, cast to it where necessary and simply call clone(). But that does force you to make clone() public, while you may want to keep it protected (don't ask me why).
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!