JDK-6550652 : Instanciation of anonymous class after call to super()
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 6
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: linux
  • CPU: x86
  • Submitted: 2007-04-26
  • Updated: 2011-02-16
  • Resolved: 2007-05-14
Related Reports
Duplicate :  
Description
FULL PRODUCT VERSION :
java version "1.6.0"
Java(TM) SE Runtime Environment (build 1.6.0-b105)
Java HotSpot(TM) Client VM (build 1.6.0-b105, mixed mode, sharing)
(seen on older jvm as well)

ADDITIONAL OS VERSION INFORMATION :
Linux pc-andreas 2.6.20-15-generic #2 SMP Sun Apr 15 07:36:31 UTC 2007 i686 GNU/Linux

EXTRA RELEVANT SYSTEM CONFIGURATION :
Ubuntu Feisty

A DESCRIPTION OF THE PROBLEM :
In short, I've tried to have an abstract class that calls some abstract methods in the default constructor. So the only thing in a derived child class is to implement the abstract method & a call to super constructor, eg. for a small framework to parse different data formats without writing the io code several times. This works quite well as long as the derived child does not use a anonymous class (as in the code example) instance in this implementation. If it does the variable containing the anonymous class instance is null when the super constructor calls the method in child. I don't know if this is really a bug or a misunderstanding of the java language specification, but in the case that non-anonymous classes work it looks merely like a bug to me.


STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
compile given two classes and create a new instance of Bug.class in a main() or elsewhere

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
should print out to console following two lines:

Should work
No Bug
ACTUAL -
actually print out to console following line combined with a null pointer exception:

Should work


ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.NullPointerException
        at Bug.doSomething(Bug.java:24)
        at AbstractBug.<init>(AbstractBug.java:7)
        at Bug.<init>(Bug.java:1)
        at test.main(test.java:6)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
public abstract class AbstractBug {
	/*
	 * a constructor, calling the test method wich is implemented in CHILD
	 */
	public AbstractBug() {
		super();
		doSomething();
	}
	
	/*
	 * a test method implemented in child class
	 */
	protected abstract void doSomething();
}

public class Bug extends AbstractBug {

	/*
	 * a annonymous class
	 */
	private final Object testObject = new Object() {
		public String toString() {
			return "No Bug";
		}
	};
	
	/*
	 * a simple string
	 */
	private final String testString = "Should work";

	/*
	 * a test method called from super() constructor,
	 *
	 * should print out "Should work\nNo Bug" if correct
	 */
	protected void doSomething() {
		System.out.println(testString);
		System.out.println(testObject.toString());
	}

}

public class test
{
	public static void main(String[] args) 
	{
		System.out.println("Hello World!");
		Bug b = new Bug();
	}
}

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

CUSTOMER SUBMITTED WORKAROUND :
simply avoid using such invokations in super() constructor of abstract methods, but i though this could be a elegant solution.

Comments
EVALUATION This is not a bug. The subclass's instance variables are not initialized throughout execution of the superclass's constructor (even if it happens to invoke Bug.doSomething), and nor should they be. Avoid using polymorphism in constructors. You could imagine aggressively initializing an instance variable in a subclass iff the variable's value is something simple like a literal, but that just means even more rules. The code in this CR is isomorphic to 6275018, so I am closing it as a duplicate.
14-05-2007