Enums and ActionScript's Static Initializers

I discovered today, while trying to synthesize an Enum type, that AS3 has the concept of a static initializer, which is awesome. In a nutshell, a static initializer is kind of like a constructor, but it's for the class object itself, not instances of the class. It gets invoked during classloading, after all static properties have been set, but the class is turned loose for general consumption. Here's an example of an Enum type (named ColorEnum) that uses the static initializer (in bold):

package com.barneyb.test {

  public class ColorEnum {

    public static const BLACK:ColorEnum = new ColorEnum(0x000000);
    public static const WHITE:ColorEnum = new ColorEnum(0xFFFFFF);

    private static var locked:Boolean = false;

    {
      locked = true;
    }

    private var _color:uint;
    public function get color():uint {
      return _color;
    }

    public function ColorEnum(color:uint) {
      if (locked) {
        throw new Error("You can't instantiate ColorEnum");
      }
      _color = color;
    }
  }
}

What this provides is a ColorEnum class that cannot be instantiated, with two instances stored in the BLACK and WHITE static constants. This sort of class locking is equally useful for singletons (think ServiceLocator if you use Cairngorm, though they implement it differently). Usually, you use a private constructor for this type of behaviour, but since AS3 doesn't support that, you have to synthesize it. However, that's not all a static initializer can do.

Another use case is if you have a complex static variable that you need to initialize, but can't do in a single expression. For example, if you need to create multiple aggregated objects, you usually need multiple expressions. You can do this in a static initializer as well. Note that you can't set a static const within a static initializer, but you can set a static var (variables).

5 Responses to “Enums and ActionScript's Static Initializers”


  1. 1 Jared Rypka-Hauer

    Barney,

    It's pseudo-constructors for everyone, then, eh? :) Granted, post-classloading vs post-instantiation, but given that CF and AS3's paradigms are actually radically different, the analogy seems to resonate with me.

    J

  2. 2 barneyb

    Jared,

    The paradigms are totally incompatible.

    With a CFC, the psuedo-constructor just sits there, and when the CFC is instantiated, it gets invoked within the context of the new instance. The second time the CFC gets instantiated, it gets invoked again, again within the context of the new instance.

    With an AS class, the static initializer gets invoked when the class is loaded, with no instances of the class created. When the class is instantiated, the static initializer is NOT invoked again, only the constructor.

  3. 3 Jason Boyd

    Having seen several approaches to the Singleton case in AS3 (non-public class in constructor, using a random and/or private number, etc), this one works pretty well with minimal fuss:

    package foo
    {
    class Singleton
    {
    private static const m_instance:Singleton = new Singleton();

    public function Singleton()
    {
    if (m_instance != null) throw new Error("Noooooooo!!!!");
    // one time init code here
    }

    public static function getInstance():Singleton
    {
    return m_instance;
    }
    }
    }

    Static initializers are cool though. Thanks for the post!

  4. 4 barneyb

    Jason,

    The static initializer has a subtle benefit: no race condition. It's theoretically possible with the constructor-conditional method that two threads could instantiate objects at the same time and you end up with to singletons. Currently, the Adobe Flash player is single threaded so it's not actually possible, but that's an implementation detail.

    Because the static initializer happens at class load time, and you'll never see the same class loaded more than once, you're safe. A subtle point, and with the current implementation an irrelevant one, but still worth mentioning, I think.

  5. 5 Jason Boyd

    True and true. I tend to code all my AS3 assuming single threads, since AS3 is single-threaded. If they change this in AS4 or whenever, all bets are off.

  1. 1 Static initializers in AS3
  2. 2 » typesafe enums in as3
  3. 3 » typesafe enum abstract class
  4. 4 ActionScript Enums « The Combined Corner
  5. 5 ActionScript 3 Enums « The Combined Corner

Leave a Reply