Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4220218

Please make CloneNotSupportedException unchecked

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Won't Fix
    • Icon: P4 P4
    • None
    • 1.2.0
    • core-libs
    • generic
    • generic



      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)
      ======================================================================

            jjb Josh Bloch (Inactive)
            vasya Vassili Igouchkine (Inactive)
            Votes:
            0 Vote for this issue
            Watchers:
            0 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: