Today’s article follows up on an article I wrote way back in August of 2009 about the order of operations when you use a class. In the original article I showed the order of field initializers and constructors. Today I’m expanding on that to show three more chunks of code that are run. Can you guess what those chunks are?

The first new chunk of code that’s executed when you first use a class is the chunk that initializes static variables (and constants, but those are just syntax sugar). This chunk is executed the first time you use a class and allows you a convenient (and mandatory, in the case of constants) way of initializing static fields. This chunk looks like this:

class MyClass
{
	public static const MY_MAGIC_NUMBER:int = 12345;
}

The second new chunk is the “class constructor” or “static initialization block” or, for you avid bytecode readers, “cinit()”. This block—which is different from the “instance constructor” that’s called when you call new—is executed the first time you use a class and is intended to help you do setup work for the class, not an instance of the class. Here’s an example:

class MyClass
{
	public static var doubles:Vector.<int>;
 
	// class constructor
	{
		// NOTE: like other static functions, you can't use "this" here
 
		// Initialize the vector with double the index
		const numDoubles:int = 100;
		doubles = new Vector.<int>(numDoubles);
		for (var i:int = 0; i < numDoubles; ++i)
		{
			doubles[i] = i*2;
		}
	}
}

The third and final chunk of code is yet-another one-time block, this time presumably to set up the package the class is in. I call this the “package constructor”, for lack of a better term. If you throw an exception (which you can’t do explicitly due to an MXMLC crash but can do implicitly by calling a function like new BitmapData(0,0)), you’ll see a stack trace that calls it “global$init()”. So, I suppose, it’s sort of a global space like exists in C but not in Java. Here’s an example of how to use it:

package mypackage
{
	// "package constructor"/"global init()"
	MySingleton.init();
	MyOtherSingleton.init();
 
	public class MyClass
	{
	}
}

Honestly, I’m not entirely sure what useful code you could put there that wouldn’t better belong elsewhere (your main class’ constructor, class constructors, etc.). The only useful purpose I’ve seen it serve was pointed out in a comment on last week’s article showing how to use it for class dependencies:

package mypackage
{
	// Class dependencies. Note the class is referenced after the import.
	import otherpackage.ClassA; ClassA;
	import otherpackage.ClassB; ClassB;
 
	// This class intentionally left blank
	public class ClassDependencies {}
}

Now, with those additional chunks of code in mind, let’s look at two classes I’ve written to test the order of execution:

ClassBootupParent
package
{
	import flash.display.*;
 
	ClassBootupParent.history.push("parent package constructor");
 
	public class ClassBootupParent extends Sprite
	{
		public static var history:Array = ["parent static field initializer"];
		public var parentField:* = history.push("parent non-static field initializer");
 
		{
			history.push("parent class constructor");
		}
 
		public function ClassBootupParent()
		{
			history.push("parent constructor");
		}
	}
}
ClassBootup
package
{
	import flash.utils.*;
	import flash.text.*;
	import flash.display.*;
 
	ClassBootupParent.history.push("child package constructor");
 
	public class ClassBootup extends ClassBootupParent
	{
		public static var childStatic:* = history.push("child static field initializer");
		public var childNonStaticField:* = history.push("child non-static field initializer");
 
		{
			history.push("child class constructor");
		}
 
		public function ClassBootup()
		{
			history.push("child constructor");
 
			var tf:TextField = new TextField();
			tf.autoSize = TextFieldAutoSize.LEFT;
			tf.text = history.join("\n");
			addChild(tf);
		}
	}
}

The history fiel is used to keep a journal describing the order. When run, the app display this:

parent static field initializer
parent class constructor
parent package constructor
child static field initializer
child class constructor
child package constructor
child non-static field initializer
parent non-static field initializer
parent constructor
child constructor

First of all, it’s good to see that the chunks of code execute in at least a semi-reasonable order. First the parent statics are executed, then the child statics. Both sets of statics are executed in the same order: field initializer, class constructor, package constructor. Then, when the class is actually instantiated, we see the same bizarre results from last time. Why is it that the order is child-parent-parent-child? Add in the fact that even calling your parent’s constructor is optional and the instantiation process gets even uglier.

In conclusion, we’ve seen that the static initialization happens—as expected—before the object instantiation we saw last time. Here is the full order for your reference:

  1. Parent Statics
    1. Field initializer (public static var x:int = 3;)
    2. Class constructor (class A { {/*class constructor*/} })
    3. Package constructor (package P { /* package constructor */ class A {} })
  2. Child Statics
    1. Field initializer (public static var x:int = 3;)
    2. Class constructor (class A { {/*class constructor*/} })
    3. Package constructor (package P { /* package constructor */ class A {} })
  3. Child non-static field initializer (public var x:int = 3;)
  4. Parent non-static field initializer (public var x:int = 3;)
  5. Parent constructor (optional) (function Parent(){})
  6. Child constructor (function Child(){})