Why not cloneable by default?

T

Thomas G. Marshall

Does anyone know why the java designers didn't make every object
shallow-cloneable by default?

I understand the implications of cloning something overly hefty, and to be
cautious about such things, but it still seems a little overboard to me to
err on the side of turning if off.

Turning it off could easily have been accomplished by implementing something
called:

public interface NotCloneable {}

In fact, I might have allowed two methods, deep within Object:

public Object shallowClone()

and

public Object deepClone()

Now deep cloning is of course fraught with peril, and I am normally very
much in favor of the safety restrictions in the java language, but I'm not
sure this is the kind of thing that java should protect against.
 
A

Antti S. Brax

(e-mail address removed) wrote in comp.lang.java.p$
Does anyone know why the java designers didn't make every object
shallow-cloneable by default?
Turning it off could easily have been accomplished by implementing something
called:

public interface NotCloneable {}

Since most objects never need to be cloned this would actually
place a bigger burden on the programmer.
 
A

Alexander Mueller

Thomas said:
Does anyone know why the java designers didn't make every object
shallow-cloneable by default?

I understand the implications of cloning something overly hefty, and to be
cautious about such things, but it still seems a little overboard to me to
err on the side of turning if off.

Turning it off could easily have been accomplished by implementing something
called:

public interface NotCloneable {}

I agree that the current implementation of object cloning is rather
messy. Why does java.lang.Object provide a clone method which doesnt do
anything beside throwing an exception? Why doesnt java.lang.Cloneable
provide the actual clone method which would indicate its abstracted
being as it is wrongly semi-implemented with the exception throwing
clone method of java.lang.Object.

Right now, Java is saying a class needs to specifically indicate that it
is willing to be cloned, but at the same time Java is providing the
method to do this for every object. This is not the object oriented way
Java is usually following, but I assume this happened because of
historical reasons.

Alexander
 
A

Antti S. Brax

[email protected] wrote in comp.lang.java.programmer:
I agree that the current implementation of object cloning is rather
messy. Why does java.lang.Object provide a clone method which doesnt do
anything beside throwing an exception?

Because there is ablosutely no point in cloning instances
of java.lang.Object. You can just as well create a new object
with "new Object()".
Why doesnt java.lang.Cloneable provide the actual clone method which
would indicate its abstracted being as it is wrongly semi-implemented
with the exception throwing clone method of java.lang.Object.

Because Cloneable is an interface and interfaces can not
provide implementations of methods. If you want your objects
to be cloneable you state it by implementing Cloneable and
the implementation in java.lang.Object does the rest for you.
Right now, Java is saying a class needs to specifically indicate that it
is willing to be cloned, but at the same time Java is providing the
method to do this for every object.

Not for every object. Just for those that are marked Cloneable
by the programmer.
This is not the object oriented way
Java is usually following, but I assume this happened because of
historical reasons.

Feel free to describe a better way to implement cloneability
and we'll collectively sort out the drawbacks in those.
 
A

Alexander Mueller

Antti said:
Because there is ablosutely no point in cloning instances
of java.lang.Object. You can just as well create a new object
with "new Object()".

Of course, but why does it provide the method at all?
Because Cloneable is an interface and interfaces can not
provide implementations of methods. If you want your objects
to be cloneable you state it by implementing Cloneable and
the implementation in java.lang.Object does the rest for you.

Did I say something else? But interfaces can and do provide abstracted
methods which need to be implemented by the particular class. And this
is the perfect example for java.lang.Cloneable.
Not for every object. Just for those that are marked Cloneable
by the programmer.

No, the clone method is available for ALL objects.
Feel free to describe a better way to implement cloneability
and we'll collectively sort out the drawbacks in those.

I'd have assumed this is obvious! Just as ALL other such implementations
are done in Java.

Each class which wants to support cloning should implement
java.lang.Cloneable which would introduce clone() and then you can know
for sure that each class derived from java.lang.Cloneable supports cloning.

Alexander
 
M

Mike Schilling

Feel free to describe a better way to implement cloneability
and we'll collectively sort out the drawbacks in those.

Object defines

protected Object shallowClone();

Cloneable defines

public abstract Object clone();

An object that wants to be cloneable defines

public Object clone()
{
return shallowClone(); // Or it can customize what cloning means
for this class
}

A class that isn't cloneable no longer defines a method that always throws
an exception.

This assumes that there's some reason for only some classes the be
cloneable. Like Thomas, I'm not sure I see that.
 
G

Guest

Does anyone know why the java designers didn't make every object
shallow-cloneable by default?

I understand the implications of cloning something overly hefty, and to be
cautious about such things, but it still seems a little overboard to me to
err on the side of turning if off.

Turning it off could easily have been accomplished by implementing something
called:

public interface NotCloneable {}

In fact, I might have allowed two methods, deep within Object:

public Object shallowClone()

and

public Object deepClone()

Now deep cloning is of course fraught with peril, and I am normally very
much in favor of the safety restrictions in the java language, but I'm not
sure this is the kind of thing that java should protect against.

I believe, its correct the Object class implement clone() does nothing
except throwing an exception.

So, If programmer wants to implement clone for his class, simply
overload clone().

And other classes like Vector, Hashtable implement a new method for
recursive cloning.

But I am not a Java guru. Maybe I am wrong ;-)
 
G

Guest

I believe, its correct the Object class implement clone() does nothing
except throwing an exception.

Is there a problem if a method throws an exception? I think no.
Is there a problem if a method throws an exception in 90% of objects and
works fine on 10% of objects? I think no.
 
C

Chris Smith

I believe, its correct the Object class implement clone() does nothing
except throwing an exception.

No, that is not correct. The clone() method in Object throws an
exception only if the actual class of the object it's called on does not
implement the Cloneable marker interface. If the class implements
Cloneable, then Object provides a shallow-copy clone of the entire
object state. In fact, all implementations of clone() in non-final
classes *must* eventually delegate to Object.clone() in order to be
correctly implemented. Otherwise, they almost certainly break their
contract somewhere.

--
www.designacourse.com
The Easiest Way To Train Anyone... Anywhere.

Chris Smith - Lead Software Developer/Technical Trainer
MindIQ Corporation
 
R

Ryan Stewart

Alexander Mueller said:
I agree that the current implementation of object cloning is rather messy. Why
does java.lang.Object provide a clone method which doesnt do anything beside
throwing an exception?
Because any class that wants to clone itself must be able to first obtain a
proper clone of its superclass.
Why doesnt java.lang.Cloneable provide the actual clone method which would
indicate its abstracted being as it is wrongly semi-implemented with the
exception throwing clone method of java.lang.Object.
The clone method of Object is not wrongly implemented. An abstract method would
not fulfill the requirement above.
Right now, Java is saying a class needs to specifically indicate that it is
willing to be cloned, but at the same time Java is providing the method to do
this for every object. This is not the object oriented way Java is usually
following, but I assume this happened because of historical reasons.
Actually, only the object itself or an object closely associated with it can
attempt to clone it by default, as the clone method is protected.
 
M

Mike Schilling

Actually, only the object itself or an object closely associated with it
can attempt to clone it by default, as the clone method is protected.

Unless the object's class overrides it with

public Object clone()

In fact, the Javadoc for Cloneable says

By convention, classes that implement this interface should
override Object.clone (which is protected) with a public
method.
 
T

Tim Tyler

Alexander Mueller said:
I agree that the current implementation of object cloning is rather
messy. Why does java.lang.Object provide a clone method which doesnt do
anything beside throwing an exception? Why doesnt java.lang.Cloneable
provide the actual clone method which would indicate its abstracted
being as it is wrongly semi-implemented with the exception throwing
clone method of java.lang.Object.

Right now, Java is saying a class needs to specifically indicate that it
is willing to be cloned, but at the same time Java is providing the
method to do this for every object. This is not the object oriented way
Java is usually following, but I assume this happened because of
historical reasons.

Some relevant resources:

``If you've read the item about cloning in my book, especially if you
read between the lines, you will know that I think clone is deeply
broken. There are a few design flaws, the biggest of which is that the
Cloneable interface does not have a clone method. And that means it
simply doesn't work [...]''

It's a shame that Cloneable is broken, but it happens. The original Java
APIs were done very quickly under a tight deadline to meet a closing
market window. The original Java team did an incredible job, but not
all of the APIs are perfect. Cloneable is a weak spot, and I think
people should be aware of its limitations.''

- A Conversation with Josh Bloch http://www.artima.com/intv/bloch13.html

"Avoid implementing clone"

- http://www.javapractices.com/Topic71.cjp

Another reason clone() is bad - it returns an Object, and using it
typically forces your clients to scatter casts through their code,
making their code ugly and hard to read - and compromising the benefits
of type safety in the process.
 
T

Thomas G. Marshall

Antti S. Brax coughed up:
(e-mail address removed) wrote in
comp.lang.java.p$


Since most objects never need to be cloned this would actually
place a bigger burden on the programmer.


No. /never need/ is *radically* different to /never should be/. If most
objects *should* *never* *be* cloned, then you would be right---we would be
forced to turn off specifically every class we make.

But "never need to be cloned" per se does not matter in the least.
 
T

Thomas G. Marshall

Antti S. Brax coughed up:
[email protected] wrote in comp.lang.java.programmer:

Because there is ablosutely no point in cloning instances
of java.lang.Object. You can just as well create a new object
with "new Object()".

That doesn't answer the question. Having a Object.clone() is something that
/all/ subclasses could use, not just Object.

There is a layer of protection that they felt necessary here, but it has
nothing to do with no reason to clone Object (non subclassed) instances.


....[rip]...
 
T

Thomas G. Marshall

Is there a problem if a method throws an exception? I think no.
Is there a problem if a method throws an exception in 90% of objects
and works fine on 10% of objects? I think no.

These are grossly oversimplified statements, and do not reflect an
understanding of the issue.

 
T

Thomas G. Marshall

Chris Smith coughed up:
No, that is not correct. The clone() method in Object throws an
exception only if the actual class of the object it's called on does
not implement the Cloneable marker interface. If the class implements
Cloneable, then Object provides a shallow-copy clone of the entire
object state. In fact, all implementations of clone() in non-final
classes *must* eventually delegate to Object.clone() in order to be
correctly implemented. Otherwise, they almost certainly break their
contract somewhere.

Yes.

Part of the interesting thing about my question is that it uncovers just how
very many people simply don't understand how cloning works in the first
place.

And having to explain it obscures the question, which is not /how/ it works,
but /why/ the defaults are as they are.
 
M

Mike Schilling

"Thomas G. Marshall" <[email protected]>
wrote in message ..
Part of the interesting thing about my question is that it uncovers just
how very many people simply don't understand how cloning works in the
first place.

And having to explain it obscures the question, which is not /how/ it
works, but /why/ the defaults are as they are.

Though it suggests strongly that they're suboptimal.
 
T

Tim Tyler

Once said:
public Object shallowClone()

and

public Object deepClone()

C# does this with a single "Clone" method - but
implementing an interface which acts as a flag to
signal that deep copying is to be performed.

``a system-defined interface exists for classes and structs to declare
to the outside world that they support "deep copy" semantics. This
interface is System.ICloneable, and it has a single method: Clone''
 
C

Chris Uppal

Thomas said:
Does anyone know why the java designers didn't make every object
shallow-cloneable by default?

I'm coming late to this thread, but FWIW I think this is simply an error in the
Java design. Remember that it comes from the same timeframe as 'synchronized'
StringBuffer, and many other design errors (or sub-optimalities).

I think an argument could be made that clone() /shouldn't/ be exposed by
default, on the grounds that the semantics of copying are complicated and
context-dependent (so one size doesn't fit all), and that the clone()
peroration should therefore be something you opt-into when (and only when) you
have understood what copying means for some object.

The problem with that argument is that it (or something more-or-less similar)
could also apply to Object.equals() and in fact all of the other methods of
Object (except maybe toString()).

-- chris
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top