JDK-4206170 : Cloning inner classes
  • Type: Enhancement
  • Component: specification
  • Sub-Component: language
  • Affected Version: 1.1.6
  • Priority: P5
  • Status: Closed
  • Resolution: Won't Fix
  • OS: generic
  • CPU: generic
  • Submitted: 1999-01-27
  • Updated: 2011-10-31
  • Resolved: 2011-10-31
Description

Name: dbT83986			Date: 01/26/99


Consider this code:

public class Outer implements Cloneable
{
  int i = 5;
  Inner inner1 = new Inner();
  class Inner implements Cloneable
  {
    public String toString()
    {
      return Integer.toString( i );
    }
  }

  public Object clone()
  {
    try
    {
      Outer clone = (Outer) super.clone();
      clone.inner1 = (Inner) inner1.clone();
      return clone;
    }
    catch ( CloneNotSupportedException e )
    {
      throw new Error( "CloneNotSupported: " + e.getMessage() );
    }
  }

  public static void main( String[] args )
  {
    Outer outer1 = new Outer();
    Outer outer2 = (Outer) outer1.clone();
    outer1.i = 8;
    System.out.println( outer1.inner1 + " " + outer2.inner1 );
  }
}

When outer1 is cloned, its clone (outer2) has a
new instance of Inner for its inner1 field, but
this new instance is still considered to be
enclosed by outer1. There is no easy way of making
it part of outer2 instead since outer2 has to
construct inner1 itself in order to enclose it.

Any workarounds (e.g. below) require Inner cloning
to be done manually, and this cloning has to be
updated for changes to Inner fields. This gets
very complicated if Inner is a subclass with an
inheritance hierarchy!!

I don't have any recommendations, but I feel this
situation could be improved. Basically, I think
some way is needed of reattaching a clone of an
inner class to a different enclosing class.
(Review ID: 34066)
======================================================================

Comments
EVALUATION Proposals for new features in the Java programming language are no longer being accepted or maintained in the bug database at http://bugs.sun.com/. This also applies to proposals for new features in the Java Virtual Machine (that is, in the abstract JVM, as opposed to a JVM implementation like HotSpot). All proposals for new features should be made through the "JDK Enhancement - Proposal & Roadmap Process" described at http://openjdk.java.net/jeps/1. Consequently, this specific request to change the Java programming language will not be considered further. The bug database continues to accept and maintain submissions about technical errors in the design and specification of the Java programming language and the Java Virtual Machine.
31-10-2011

WORK AROUND Name: dbT83986 Date: 01/26/99 Declare a method in Outer that is called by Outer.clone(), e.g. private void cloneInner() { Inner oldInner = inner1; inner1 = new Inner(); // copy all fields from oldInner to inner1 explicitly } Outer.clone() would then replace its clone inner1 statement by: clone.cloneInner(); ======================================================================
11-06-2004

EVALUATION I think that Object.Clone for an inner class might profitably accept an outer instance argument, for the same reason that 'new' for an inner class allows an outer instance to be specified. Of course, the result is not exactly what clone is supposed to do. The outer instance is simply a field of an inner instance, and Object.clone does a shallow copy that shares the (reference) values of fields of reference type. william.maddox@Eng 1999-01-29 I can't do anything in the compiler without a specification, so I'm reclassifying this as a specification issue. My inclination would be to decline. neal.gafter@Eng 2000-12-15 I think the operative sentence in the bug report is " I don't have any recommendations". Manual control over the cloning is tiresome, but is at least explicit. I would be reluctant to add further automagical behavior for inner classes. We might reconsider if/when the class file format and VM gave better support for inner classes. gilad.bracha@eng 2001-01-04
04-01-2001