JDK-4220218 : Please make CloneNotSupportedException unchecked
  • Type: Enhancement
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.2.0
  • Priority: P4
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 1999-03-14
  • Updated: 2014-12-05
  • Resolved: 2003-06-23
Related Reports
Duplicate :  
Description

Name: vi73552			Date: 03/14/99


CloneNotSupportedException should extend RuntimeException instead
of Exception. This would make it an unchecked exception which
in my opinion it should have been from the start.

My main reason for this is that you must often create try..catch
blocks to absorb a CloneNotSupportedException when its obvious
that one could never be thrown. For example:

class Sheep implements Cloneable {
    public Object clone() {
        try {
            return super.clone();
        } catch (CloneNotSupportedException e) {
            // This would never happen, but the compiler doesn't know that
        }
    }
}

Now suppose you want to prevent your class from being cloned.
However, the class it extends implements Cloneable using the 
pattern shown above. The logical thing to do is to throw
CloneNotSupportedException, however the compiler disallows it 
because its a checked exception and it doesn't appear in the
"throws" clause for the super class's clone() method.

class Dolly extends Sheep {
    public Object clone() {
        // This is the logical way to prevent cloning, but the compiler disallows it
        throw new CloneNotSupportedException();
    }
}

You could work around this problem if Sheep.clone() had "throws 
CloneNotSupportedException" on the off chance that some sub-classes
might not want to be cloned. But this just aggravates the first
problem by forcing each caller to handle a CloneNotSupportedException 
that will never be thrown (99% of the time).

Normally, I wouldn't recommend making a change like this so late
in the game. However, I believe the change can be made with only
a slight risk of introducing incompatibilities with previous
versions of Java.

At a source code level, there should be no problem. Older sources
will continue to compile correctly. In particular, the compiler
will not complain if the programmer puts "throws CloneNotSupportedException"
in a method's declaration. Unchecked exceptions may appear in
a method's throws clause even though its not necessary.

At a byte code level, existing classes should continue to behave
as before. In particular, the VM does not use the information
in the method's throws clause to restrict which exceptions may be
thrown.

There is in fact only one case I can find where making this change
could lead to undesirable behavior. Take a look at the following
code:

void useCloneMethod(Foo foo) {
    try {
        Foo clone = (Foo)foo.clone();
    } catch (RuntimeException re) {
        // Handle unchecked exceptions here (such as NullPointerException)
    } catch (CloneNotSupportedException cnse) {
        // Handle CloneNotSupportedExceptions here
    }
}

With the current version of Java, CloneNotSupportedException would
be handled by the second catch block. However, if you make the changes
I've requested, CloneNotSupportedExceptions would then be handled 
by the first catch block. Depending on what these catch blocks
do its possible that a program would behave incorrectly. If the
above program were recompiled, the compiler would complain that
the second catch block is unreachable. However, I think that
very few programs use code similar to the method above and therefore
it represents only a very slight risk of creating incompatibilities
between different versions of Java.
(Review ID: 55475) 
======================================================================

Comments
EVALUATION I am in complete agreement that CloneNotSupportedException should have been unchecked. Whether it makes sense to change it now is less clear. The clone facility suffers from serious design flaws. It was proposed that these flaws be fixed as part of Merlin, but the proposal was ultimately rejected as too disruptive. At this point, the clone facility is of very limited utility, so it is not clear that it is worth putting band aids on it. The best policy is generally not to use it. joshua.bloch@Eng 2001-03-03
03-03-2001