CloneNotSupportedException should extends RuntimeException not Exception

Jeroen Frijters jeroen at sumatra.nl
Mon Oct 15 19:34:52 UTC 2012


I wrote:
>The point about a non-final class being cloneable is simply that a base class can always implement Cloneable, so that interface is currently meaningless.

Obviously that should read "... a derived class can always implement Cloneable..."

Regards,
Jeroen
________________________________________
From: core-libs-dev-bounces at openjdk.java.net [core-libs-dev-bounces at openjdk.java.net] on behalf of Jeroen Frijters [jeroen at sumatra.nl]
Sent: Monday, October 15, 2012 9:30 PM
To: Remi Forax
Cc: David Holmes; core-libs-dev at openjdk.java.net
Subject: RE: CloneNotSupportedException should extends RuntimeException not     Exception

Hi Rémi,

The point about a non-final class being cloneable is simply that a base class can always implement Cloneable, so that interface is currently meaningless.

With the static method approach, the Cloneable interface becomes a valid way to opt in to that, but I see two downsides to the static method approach:

1. Once you allow your object to be cloneable, you can't prevent others from cloning your instances. So this pattern wouldn't work:

public Foo copy() {
  Foo theCopy = (Foo)shallowClone();
  theCopy.someArray = theCopy.someArray.clone();
  return theCopy;
}

2. The Cloneable interface check is an unnecessary perf hit. The admittedly ugly downcast in the above code can be easily optimized away.

The perf is not a showstopper, but 1. is in my opinion.

Regards,
Jeroen
________________________________________
From: Remi Forax [forax at univ-mlv.fr]
Sent: Monday, October 15, 2012 7:08 PM
To: Jeroen Frijters
Cc: David Holmes; core-libs-dev at openjdk.java.net
Subject: Re: CloneNotSupportedException should extends RuntimeException not Exception

Hi Jeroen,

On 10/15/2012 01:48 PM, Jeroen Frijters wrote:
> The solution is actually pretty easy. Just deprecate Object.clone() and add a new method to Object:
>
> protected final native Object shallowClone();
>
> It doesn't require the useless Cloneable interface and doesn't conflate shallow and deep cloning.
>
> (This is similar to .NET's Object.MemberwiseClone().)
>
> Note that this means that any non-final class is cloneable, BUT THAT IS ALREADY THE  CASE even though some people want to pretend otherwise.

To avoid collisions it can be a static method of Object or j.u.Objects
that uses generics to be nicely typed.

static native <T> T shallowClone(T object);

and I disagree about Cloneable, while a non-final class is by definition
mutable, it doesn't mean
that a non final class can be cloned because it may share some states
that should not be shared,
at least without the consent from the author the class.

The other nice property is that any cloneable class will be publicly
cloneable.

I also believe that the checkcast generated by javac before calling
shallowClone can be removed
by the JIT, currently this cast is not removed when you call clone.

>
> Regards,
> Jeroen

regards,
Rémi


More information about the core-libs-dev mailing list