JDK-4906931 : Extended innerclasses cant access outerclass during base innerclass construction
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 1.4.2
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: solaris_8
  • CPU: sparc
  • Submitted: 2003-08-14
  • Updated: 2003-08-14
  • Resolved: 2003-08-14
Related Reports
Duplicate :  
Description

Name: gm110360			Date: 08/14/2003


FULL PRODUCT VERSION :
java version "1.4.1"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.1-b21)
Java HotSpot(TM) Client VM (build 1.4.1-b21, mixed mode)


FULL OPERATING SYSTEM VERSION :
SunOS pegasus 5.8 Generic_108528-16 sun4u sparc
SUNW,Sun-Blade-1000


ADDITIONAL OPERATING SYSTEMS :
Windows 2000


A DESCRIPTION OF THE PROBLEM :
An extended inner class can not access its outer class while
the base inner class is being constructed.

The source code below demonstrates the problem where the
following exception occurs.

Exception in thread "main" java.lang.NullPointerException
        at
InnerClassTest$ExtendedInnerClass.getData(InnerClassTest.java:37)
        at
InnerClassTest$BaseInnerClass.<init>(InnerClassTest.java:21)
        at
InnerClassTest$ExtendedInnerClass.<init>(InnerClassTest.java:32)
        at InnerClassTest.<init>(InnerClassTest.java:13)
        at InnerClassTest.main(InnerClassTest.java:5)


The problem seems to be during the construction of the
extended inner class because its reference isnt initialised
until after the base inner classes constructor has
completed. Which seems to be reasonable because of the order
of running the constructors.


Removing the getData call from the constructor and placing
it in the inner class test as follows

	new BaseInnerClass().getData();
	new ExtendedInnerClass().getData();

works fine.


Could and should the extended inner class share the base
inner classes reference to the outer class?

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
1. Run the attached program.

EXPECTED VERSUS ACTUAL BEHAVIOR :
The expected results are:



Constructing Base Class
InnerClassTest$BaseInnerClass@614475
InnerClassTest@1d5816c
Getting Base Data
InnerClassTest$BaseInnerClass@614475
InnerClassTest@1d5816c

Constructing Base Class
InnerClassTest$ExtendedInnerClass@23e7ba
InnerClassTest@1d5816c
Getting Extended Data
InnerClassTest$ExtendedInnerClass@23e7ba
InnerClassTest@1d5816c



But the actual results are



Constructing Base Class
InnerClassTest$BaseInnerClass@614475
InnerClassTest@1d5816c
Getting Base Data
InnerClassTest$BaseInnerClass@614475
InnerClassTest@1d5816c

Constructing Base Class
InnerClassTest$ExtendedInnerClass@23e7ba
InnerClassTest@1d5816c
Getting Extended Data
InnerClassTest$ExtendedInnerClass@23e7ba
null
Exception in thread "main" java.lang.NullPointerException
        at
InnerClassTest$ExtendedInnerClass.getData(InnerClassTest.java:37)
        at
InnerClassTest$BaseInnerClass.<init>(InnerClassTest.java:21)
        at
InnerClassTest$ExtendedInnerClass.<init>(InnerClassTest.java:32)
        at InnerClassTest.<init>(InnerClassTest.java:13)
        at InnerClassTest.main(InnerClassTest.java:5)


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NullPointerException
        at InnerClassTest$ExtendedInnerClass.getData(InnerClassTest.java:37)
        at InnerClassTest$BaseInnerClass.<init>(InnerClassTest.java:21)
        at InnerClassTest$ExtendedInnerClass.<init>(InnerClassTest.java:32)
        at InnerClassTest.<init>(InnerClassTest.java:13)
        at InnerClassTest.main(InnerClassTest.java:5)


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------

public class InnerClassTest {
    
    public static void main(String[] args) {
	new InnerClassTest();
    }
    
    Object object;
    
    InnerClassTest() {
	new BaseInnerClass();
	System.out.println();
	new ExtendedInnerClass();
    }
    
    class BaseInnerClass {
	BaseInnerClass() {
	    System.out.println("Constructing Base Class");
	    System.out.println(this);
	    System.out.println(InnerClassTest.this);
	    getData();
	}
	
	Object getData() {
	    System.out.println("Getting Base Data");
	    System.out.println(this);
	    System.out.println(InnerClassTest.this);
	    return object;
	}
    }
    
    class ExtendedInnerClass extends BaseInnerClass {
	Object getData() {
	    System.out.println("Getting Extended Data");
	    System.out.println(this);
	    System.out.println(InnerClassTest.this);
	    return object;
	}
    }
}

---------- END SOURCE ----------

CUSTOMER WORKAROUND :
Restructure you code differently but the may not be as elegant
(Incident Review ID: 178350) 
======================================================================

Comments
PUBLIC COMMENTS ...
10-06-2004