Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsWhite Papers
Discussion GroupsFirst AidDatabasesJavaBeansGUIJava 3DVirtual MachineCORBASecurityToolsGeneral
Java DirectoryOpen Source ProjectsSample Book ChaptersUser GroupsWeb Resources
Related Topics
Databases.NETMore Topics ...

Java Forum / General / May 2007

Tip: Looking for answers? Try searching our database.

Creating A Copy

Thread view: 
Jason Cavett - 01 May 2007 20:13 GMT
I want to create a copy of a set of data (so I can manipulate it, etc
without affectnig any of the original data).  Currently, I am using a
deep copy that I discovered online.  The problem with the deep copy is
that it creates copies of EVERYTHING - listeners, etc, etc.  This
means that there's a whole lot of crap that has to be serializable.  I
would rather just make a copy of the data (parent class and its
children).

How would I go about creating a new object with the same data, but the
data is not a reference but an actual copy?

Thanks
Tom Hawtin - 01 May 2007 20:20 GMT
> I want to create a copy of a set of data (so I can manipulate it, etc
> without affectnig any of the original data).  Currently, I am using a
[quoted text clipped - 3 lines]
> would rather just make a copy of the data (parent class and its
> children).

You can make the fields you are not interested in transient.

> How would I go about creating a new object with the same data, but the
> data is not a reference but an actual copy?

It's fairly easy to write a method that creates a copy of an object
(well, it gets more complicated if you can have cycles). For example:

public final class MyClass {
    // @NonNull
    private SomeClass data;
    private MyClass(MyClass orig) {
        this.data = orig.data.copy();
    }
    public MyClass copy() {
        return new MyClass(this);
    }
    ...
}

Tom Hawtin
Jason Cavett - 01 May 2007 20:37 GMT
> > I want to create a copy of a set of data (so I can manipulate it, etc
> > without affectnig any of the original data).  Currently, I am using a
[quoted text clipped - 26 lines]
>
> Tom Hawtin

Where does Cloneable come into play here?  I just made my parent class
implement Cloneable, used the Object.clone() method,
and...well...frankly...everything appears to have worked correctly.  I
haven't tested all of this yet, but I'm doing that right now.

Also, if something is Cloneable, it doesn't need to be Serializable,
does it?  (Does cloning rely on that?)
Tom Hawtin - 01 May 2007 20:55 GMT
> Where does Cloneable come into play here?  I just made my parent class
> implement Cloneable, used the Object.clone() method,
> and...well...frankly...everything appears to have worked correctly.  I
> haven't tested all of this yet, but I'm doing that right now.

Cloneable is evil. It just does a naive 'bitwise' copy.

> Also, if something is Cloneable, it doesn't need to be Serializable,
> does it?  (Does cloning rely on that?)

Cloneable and Serializable are entirely independent.

Tom Hawtin
Jason Cavett - 01 May 2007 21:02 GMT
> > Where does Cloneable come into play here?  I just made my parent class
> > implement Cloneable, used the Object.clone() method,
[quoted text clipped - 9 lines]
>
> Tom Hawtin

It's evil?  But...it seems to work so well.  Haha.

And a "naive bitwise copy" - can you explain a bit more?  (In the
meantime, I'll look it up online.)
Mark Rafn - 01 May 2007 21:54 GMT
>I want to create a copy of a set of data (so I can manipulate it, etc
>without affectnig any of the original data).

Ok, so implement a copy constructor, a copyOf() method, or some other way
to create the copy.  For simple objects, the clone() method can work, but it's
been abused a lot and does the wrong thing for many objects, so many are
rightly suspicious of it.

The thing that people get wrong ALL THE TIME when discussing this is to think
that "copy" is a well-defined term which should have exactly one
implementation.  NO!  Each class has specific requirements about what its
data means, and how (and whether) it should be copied.

>Currently, I am using a deep copy that I discovered online.  The problem
>with the deep copy is that it creates copies of EVERYTHING - listeners, etc,
>etc.  This means that there's a whole lot of crap that has to be serializable.

To rephrase, "the problem with a deep copy is that I don't want a deep copy".
You'll have the opposite problem with a shallow copy.   You want a copy that
knows which members should be copied and which should themselves have a
duplicate instance created, and how to create those duplicates.

So write it.

>How would I go about creating a new object with the same data, but the
>data is not a reference but an actual copy?

Write code to do it.  There's no magic except in your brain that knows which
members should be copied, reused, or set to null.
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>
Jason Cavett - 02 May 2007 13:46 GMT
> >I want to create a copy of a set of data (so I can manipulate it, etc
> >without affectnig any of the original data).
[quoted text clipped - 27 lines]
> --
> Mark Rafn    d...@dagon.net    <http://www.dagon.net/>  

Okay.  Good point.  The thing is, cloning seems to work.

I'll try creating a copy [constructor|method|something] and see how
that works.

Thanks
Jason Cavett - 02 May 2007 14:07 GMT
> > >I want to create a copy of a set of data (so I can manipulate it, etc
> > >without affectnig any of the original data).
[quoted text clipped - 36 lines]
>
> - Show quoted text -

Meh.  I just realized why I didn't do this in the first place.

I need to be able to copy generically (aka, I know the superclass
type, but I won't necessarily know the subclass type at runtime).  The
superclass is a hierarchy of itself (type-wise).  So, I know the
parent, children and basic parameters.  The problem is that I don't
know specifics about any of those.

Maybe I didn't get enough sleep last night, but I'm stumped.
Jason Cavett - 02 May 2007 15:30 GMT
> > > >I want to create a copy of a set of data (so I can manipulate it, etc
> > > >without affectnig any of the original data).
[quoted text clipped - 48 lines]
>
> - Show quoted text -

The other issue I'm having is that, what I am copying, is a tree-type
structure.  Originally I was using Serialization (and Input/Output
streams) to perform the copy.  This didn't work when I used an object
(not one that I created) that was not Serializable.  That's why I
started looking for other alternatives.

Yes, I *could* hard-code in the copy.  That is a solution, but
considering how many objects this tree-structure can hold, it really
doesn't scale very well and doesn't make a whole lot of sense.

This is where I get stuck.  It would be great if there was a way to
ignore certain things in the Serialization copy and keep others.  But,
I haven't yet been able to figure out a way to do this.  Do you have
any suggestions?

Thanks
Lew - 02 May 2007 15:56 GMT
> Yes, I *could* hard-code in the copy.  That is a solution, but

And should.

> considering how many objects this tree-structure can hold, it really
> doesn't scale very well and doesn't make a whole lot of sense.

Declare an overridable copy( T ) method in the supertype for the nodes.  There
is such a supertype, right?  An interface?

Perhaps you can use clone() in an abstract superclass implementation, so that
it will work for cases where it will work, no need to override.  If a subclass
can't use clone() effectively, write a detailed implementation for that class.

> This is where I get stuck.  It would be great if there was a way to
> ignore certain things in the Serialization copy and keep others.  But,
> I haven't yet been able to figure out a way to do this.  Do you have
> any suggestions?

No serialization needed with a copy( T ).

I don't think there's any real magic bullet that gets you out of writing code
here.  It is logical for a type to know how to copy itself, so it's code well
worth writing.

Signature

Lew

Jason Cavett - 02 May 2007 16:18 GMT
> > Yes, I *could* hard-code in the copy.  That is a solution, but
>
[quoted text clipped - 23 lines]
> --
> Lew

Yeah, I have an abstract supertype.

The point that was confusing me is that the object I'm copying is a
tree-like structure (and, is, in fact the bases for a JTree).  So, I
need to worry about recursion, etc.

Alright, I'll give it a shot.

(As for the magic bullet - serialization actually works great.  The
only problem is, one of the objects in one class is not Serializable
and it's not my class, so I can't change that.  Sooo...that was end of
that.)
Lew - 02 May 2007 18:54 GMT
> (As for the magic bullet - serialization actually works great.  The
> only problem is, one of the objects in one class is not Serializable
> and it's not my class, so I can't change that.  Sooo...that was end of
> that.)

You can still serialize the object.

Let us say you have a class Foo with a member Baz that you don't control.

public class Foo
{
  transient private Baz baz;
  ...
}

Making the Baz element transient simply means you have to manually serialize
and deserialize the Baz object.  The fact that Baz is not Serializable is
moot; no one is using Baz to try.  That could be complicated if Baz is a
collection itself, but let's assume it's some sort of fairly uncomplicated
class with serializable attributes.

<http://java.sun.com/javase/6/docs/api/java/io/Serializable.html>
explains to use

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException;
and

 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException;

You write these methods to [de]serialize the well-known parts of Baz (untried,
untested):

 private void writeObject(java.io.ObjectOutputStream out)
     throws IOException
 {
  out.defaultWriteObject();
  out.writeObject( baz.getIntegerValue() );
  out.writeObject( baz.getStringValue() );
 }

 private void readObject(java.io.ObjectInputStream in)
     throws IOException, ClassNotFoundException
 {
  in.defaultReadObject();
  baz.setIntegerValue( (Integer) in.readObject() );
  baz.setStringValue( (String) in.readObject() );
 }

Then it matters not that Baz is not Serializable.

Signature

Lew

Mark Rafn - 02 May 2007 21:46 GMT
>The point that was confusing me is that the object I'm copying is a
>tree-like structure (and, is, in fact the bases for a JTree).  So, I
>need to worry about recursion, etc.

Fairly easy, as long as each type knows how to copy itself.  It gets tricky
when you have cycles in your reference graph, as you need to track copying
objects and references to objects separately.  It's here that serialization
starts to look tempting.

>(As for the magic bullet - serialization actually works great.  The
>only problem is, one of the objects in one class is not Serializable
>and it's not my class, so I can't change that.  Sooo...that was end of
>that.)

No, you just need to make it transient and implement a readObject and
writeObject method that properly handles saving and restoring it (if needed).
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>
Jason Cavett - 03 May 2007 15:46 GMT
> >The point that was confusing me is that the object I'm copying is a
> >tree-like structure (and, is, in fact the bases for a JTree).  So, I
[quoted text clipped - 14 lines]
> --
> Mark Rafn    d...@dagon.net    <http://www.dagon.net/>  

Thanks for all the answers.  I appreciate all your help and your
expertise on the subject.  This is new ground for me, so any
explanation is helpful.

If I don't care about copying certain parts, can I just make that
field transient and not worry about it?  I'm not sure how well that'll
work, but I tried to copy just the data as you suggested (by having
each class know how to copy itself), but I had *major* problems doing
this.  (The whole tree structure really seems to mess things up.)
Serialization was working before.  That one object was not
serializable, so that's why I couldn't continue to use it.  So, is it
possible to just completely ignore that object?
Hendrik Maryns - 03 May 2007 16:49 GMT
Jason Cavett schreef:

>>> The point that was confusing me is that the object I'm copying is a
>>> tree-like structure (and, is, in fact the bases for a JTree).  So, I
[quoted text clipped - 25 lines]
> serializable, so that's why I couldn't continue to use it.  So, is it
> possible to just completely ignore that object?

‘transient’ has only a meaning if you use serialization to copy the
objects.  However, that is not what serialization was designed for.

As a lot of people have suggested by now: the semantics of copying is
depends on the object to be copied.  Since we know nothing about what
you exactly want to do with your tree-like structure, the only
suggestion we can give is: implement it yourself.  That is, if you want
to use the clone() method, implement it (preferably by invoking
super.clone() as first statement, and then doing stuff with that).

H.

- --
Hendrik Maryns
http://tcl.sfs.uni-tuebingen.de/~hendrik/
==================
http://aouw.org
Ask smart questions, get good answers:
http://www.catb.org/~esr/faqs/smart-questions.html
Mark Rafn - 03 May 2007 17:08 GMT
>> >(As for the magic bullet - serialization actually works great.  The
>> >only problem is, one of the objects in one class is not Serializable
>> >and it's not my class, so I can't change that.  Sooo...that was end of
>> >that.)

>> No, you just need to make it transient and implement a readObject and
>> writeObject method that properly handles saving and restoring it (if needed).

>If I don't care about copying certain parts, can I just make that
>field transient and not worry about it?

Yes, but be aware that it will be null when deserialized, so you have to deal
with setting it somehow if it's important.  If it's not important, you should
just remove it entirely from your object :)
--
Mark Rafn    dagon@dagon.net    <http://www.dagon.net/>
Jason Cavett - 03 May 2007 17:53 GMT
> >> >(As for the magic bullet - serialization actually works great.  The
> >> >only problem is, one of the objects in one class is not Serializable
[quoted text clipped - 11 lines]
> --
> Mark Rafn    d...@dagon.net    <http://www.dagon.net/>  

Okay, I was reading that as one of the problems.  Unfortunately, the
issue that was happening was that, when I was serializing the object,
it serializes EVERYTHING (listeners, observers and their observers,
etc.) so things were being serialized that I don't really care about
with respect to this object (some of those listeners and observers
need to stay, though - just not all of them).  Specifically, there are
two fields that I could ignore via transient.  I did, and everything
appears to be working correctly.

It's times like these I wish I had someone to help review my design,
but, when you work in a small group and there aren't many (any) other
programmers around, it's hard to bounce ideas off people.  I
appreciate your feedback, though.  Thanks again.


Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.