Mike Chambers

code = joy

ActionScript 3 : Get a Class Reference by Class Name

with 24 comments

If you need to get a reference to a class in ActionScript 3, but only know the class name, then you can use the flash.utils.getDefinitionByName to create an instance of the class.

For example:

package
{
	import flash.display.Sprite;
	import flash.utils.getDefinitionByName;

	public class DynamicCall extends Sprite
	{
		public function DynamicCall()
		{
            var ClassReference:Class = getDefinitionByName("String") as Class;
            var s:String = (new ClassReference("foo=") as String);
            trace(s);
		}
	}
}

This basically creates an instance of the String class, from the class name “String”. getDefinitionByName takes the entire class path, so if you wanted to create an instance of MovieClip, you would provide the entire path:

            var ClassReference:Class = getDefinitionByName("flash.display.MovieClip") as Class;

Anyways, pretty simple stuff, but can come in useful.

Written by mikechambers

June 22nd, 2006 at 10:29 am

Posted in General

24 Responses to 'ActionScript 3 : Get a Class Reference by Class Name'

Subscribe to comments with RSS

  1. Cool!

    Would this be akin to using the following in AS2?
    var myClass:Test = new _global["Test"](parm);

    I’d like to see the reverse become possible too, so that any class you create transparently has a className property available, which returns a string. :)

    Mike J

    22 Jun 06 at 10:53 am

  2. Mike: You can use flash.utils.getQualifiedClassName() to go backwards and there’s also a flash.utils.describeType() which will tell you a lot more about a class in the form of XML.

    senocular

    22 Jun 06 at 12:11 pm

  3. Hey thanks Senocular.
    I always wanted to do this in my development but as I still code in AS2, I could not make it so easily.
    Now I have a good reason to have a closer look to AS3.

    Bazard

    22 Jun 06 at 8:51 pm

  4. ActionScript 3, hip hip hooray (not). I almost don’t even have the words Mike. Adobe has let down it’s loyal Mac using fans again with no Flex Builder 2 for us. Over half a year ago I was so excited when I noted a snippet about Flex Builder 2 for OS X, here we are at release time and nothing, nadda. I honestly don’t know what to say. I’m crushed, frustrated, angry, and so forth. Maybe it sounds silly, but it’s true. I’m ready to say forget Apollo too. I’m losing all interest in these corporate jerks. Sorry to bother Mike, but you’re the only one at Adobe who I thought might listen. Adobe has etched itself into a dark, dark corner of my own mindshare, and I’m probably not alone. Sigh. It might be time to turn the tables on Adobe. Thanks for listening Mike. -jt

    Jacob

    28 Jun 06 at 3:05 pm

  5. hey Mike,

    Am not sure about the class, but I’ve seen a very similar method somewhere in the mx.utils package. I dont have Flash 8 installed right now, so cant point the exact location.
    My point is, if am not wrong, a AS2 implementation of the same was there somewhere hidden in the mx.utils package..

    Arul Prasad

    3 Jul 06 at 2:57 am

  6. I find if this class creat by myself ,it can’t creact. For example: var ClassReference:Class = getDefinitionByName(”com.freelystone.face.SysManage”) as Class;
    The “com.freelystone.face.SysManage” is a class created by myself.If is run the system print “ReferenceError: Error #1065: “; Can you tell me how to amend my code.

    Zeng

    18 Jul 06 at 7:43 pm

  7. How do you get references to all fields and methods in the class by reflection? Can do it in Java pretty easily - is it possible with Actionscript?
    Thanks,
    Vicki

    how do you get all fields and methods in the class by reflection?

    5 Oct 06 at 9:34 am

  8. Has anyone managed to instantiate a class from a loaded child swf?

    eg.

    mc in the child swf with dynamically generated class definition of ‘MyClass’

    then in the parent once the child has loaded

    getDefinitionByName(”MyClass”); // doesn’t work…

    Any ideas?

    Thanks,

    James

    James

    2 Dec 06 at 8:59 am

  9. Like Zeng, I have been trying to implement this type of system using a class I have created and I’m not successful. Is there any trick to get the compiler to resolve your own “com.xyz” location?

    Thanks!

    Anon

    13 Dec 06 at 2:42 pm

  10. Unluckily, you have to declare a variable of “myclass” type in order to use getDefinitionByName with that classes.

    I’ve written a tutorial in As3Guru:
    http://www.as3guru.com/?p=5

    Enrico Foschi

    30 Jan 07 at 6:13 am

  11. @Zeng, Anon, Enrico,
    actually, you can also prevent the compiler from excluding assumably unused classes by including those classes manually. setting additional compiler argument:
    -includes=com.test.Test, com.test.AnotherTest
    would do the trick.

    Of course it can be quite annoying to specify 20 or more classes this way; in that case, use the ‘include-libraries’ directive to include a whole swc-lib :)

    Matthias Eichstedt

    1 Mar 07 at 5:19 am

  12. Is it possible to use this method for attaching library assets from a loaded child swf? Similar to what Zeng was asking. I want to load a swf with items in the library and then attach those items to the stage from somewhere else. i keep getting told the variable i’m passing to getDefinitionByName is not ddefined…

    this my function:

    public static function attachSprite(target:Sprite, linkage:String):Sprite
    {
    var ClassDefinition:Class = Class(getDefinitionByName(linkage));
    var skinObject:Object = new ClassDefinition();

    var sprite:DisplayObject = target.addChild(DisplayObject(skinObject));

    return Sprite(sprite);
    }

    Trevor

    16 Mar 07 at 8:29 am

  13. this is just what i was looking for.. i’ve created a class to ‘attach’ imported images from the library to the stage instead of the new ugly way.

    old way:
    new Bitmap(new MyAttachedImage(0,0));

    my way:
    new ImportedBitmap(’MyAttachedImage’);

    class:
    package
    {
    import flash.display.Bitmap;
    import flash.utils.getDefinitionByName;

    public class ImportedBitmap extends Bitmap
    {
    public function ImportedBitmap($bmp:String):void
    {
    var $class:Class = getDefinitionByName($bmp) as Class;
    var $data:BitmapData = new $class(0,0) as BitmapData;
    super($data);
    }
    }
    }

    roelof

    2 Nov 07 at 12:30 am

  14. Mike

    The problem that Enrico describes still exists.

    So if I want to write code that dynamically creates a user interface based on metadata that’s passed in at run time, I need to declare one of each kind of possible UI component that’s likely to be instantiated using getDefinitionByName().

    That’s tedious and not too flexible.

    Is anyone working on a way to fix this?

    Bernard Farrell

    6 Nov 07 at 6:38 pm

  15. Well, im dealing with the same issue.
    I want to force the (flash) compiler to import class which i don’t use.
    In theory there must be some way to force it to do so.

    Macromedia documentation says:
    “If you import a class but do not use it in your script, the class is not exported as part of the SWF file. This means you can import large packages without being concerned about the size of the SWF file; the bytecode associated with a class is included in a SWF file only if that class is actually used. One disadvantage of importing classes that you do not need is that you increase the likelihood of name collisions.”

    Maybe there is some hidden statement like:
    force import com.example.*

    For now i will use the following:

    package example
    {
    import example.items.*;
    import flash.utils.getDefinitionByName;

    class Test
    {
    private var _class1:example.items.Class1;
    private var _class2:example.items.Class2;

    public function Test()
    {
    var test:Class = getDefinitionByName(”example.items.Class1″) as Class;

    var testInstance = new test();
    }
    }
    }

    Someone has more ideas, except from using another compiler?

    Kees van Dorp

    14 Nov 07 at 3:31 pm

  16. I have found a solution that addresses the dynamic creation issue that some of you are experiencing. Check this out:

    http://jwopitz.wordpress.com/2008/02/21/getdefinitionbyname-trick/

    jwopitz

    21 Feb 08 at 3:27 pm

  17. Vicki asked:
    How do you get references to all fields and methods in the class by reflection? Can do it in Java pretty easily - is it possible with Actionscript?
    Thanks,
    Vicki

    @Vicki:
    You can use flash.utils.describeType to get an xml obj of all the publicly accessible properties and methods. You can also get more in depth details like metadata tags in the classes by using the following compiler options:

    -keep-as3-metadata ArrayElementType anotherMetaTag yetAnotherMetaTag yourOwnCustomMetadataTag

    combining describeType with getDefinitionByName is a powerful combination indeed.

    jwopitz

    21 Feb 08 at 3:41 pm

  18. @Arul Prasad : Thank you soooooo much !
    The path of this usefull class is : mx.utils.ClassFinder

    AS2 is not dead ;-)

    Fro

    2 May 08 at 1:32 pm

  19. there’s a way to load classes which are inside libraries of swfs load externally, and you can call those classes from teh main swf which loads that swf, the sample is on the flash documentation for as3, inside the chapter USING MOVIE CLIPS (RuntimeAssetsExplorer). (oskaraqp@hotmail.com)

    Oscar

    29 Jul 08 at 11:32 pm

  20. Mike,

    Is this possible, if I have an object of any class and I want class name of that object?

  21. u dont have to create a variable, its enough just to reference to the class somewhere in the code;

    package example
    {
    import example.items.*;
    import flash.utils.getDefinitionByName;

    // force import
    example.items.Class1;
    example.items.Class2;

    class Test
    {
    public function Test()
    {
    var test:Class = getDefinitionByName(”example.items.Class1?) as Class;

    var testInstance = new test();
    }
    }
    }

    jacob

    12 Oct 08 at 7:25 pm

  22. I’m not sure how the snippet:
    var s:String = (new ClassReference(”foo=”) as String);

    …is that handy. how would you give the variable a “String” type if it was suppose to be dynamic (or unknown) in the first place?

    Am I interpreting that incorrectly?

    Jeremy Daley

    22 Oct 08 at 2:10 pm

  23. example not working…

    N

    18 Dec 08 at 1:42 am

  24. Getting error in :-
    var str:String=”fl.transitions.Tween”;
    var obj=getDefinitionByName(str) as Class;
    trace(obj);

    why this is coming only in fl package

    Ajitpal

    2 Jan 09 at 4:21 am

Leave a Reply