Mike Chambers

code = joy

ActionScript 3 : Get a Class Reference by Class Name

with 36 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

36 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

  25. Hello

    Please help me brothers. How can I get the entire class path by class name in actionscript 3. For instance `

    var className:String = ‘Sprite’;
    var package:String = getPackage(className);

    Is there such a technic?
    Thanks in advance

    Sergey

    23 Mar 09 at 12:55 am

  26. Sergey, I don’t believe what you’re asking is possible, because “Sprite” in a string representation could belong to:
    flash.display.Sprite

    or any other custom “Sprite” class path you’ve written:
    com.sergey.custom.Sprite

    You can, however, get the fully qualified class path of a Sprite object:
    var classPath:String = getQualifiedClassName(new Sprite())

    Jeremy Daley

    22 Apr 09 at 1:20 pm

  27. Its worth mentioning, for people who prefer to use a ‘cleaner’ coding style, that you can use the flex compiler option “includes” to explicitly include classes in your swf, whether they are referenced or not. This way, you don’t have to declare any variables on your code.

    I usually use a config file instead of the command line, here’s an example:

    yourpackage.YourClass
    yourpackage.YourOtherClass

    Note that the node is not a child of the node.

    With this done, you won’t need to declare any instances of the classes you’d like to reference dynamically by using util.getDefinitionByName() or ApplicationDomain.getDefinition().

    Harold Brenes

    9 May 09 at 4:14 pm

  28. Pardon me, it seems that the comments strip away any text containing html-style tags.

    The example provided is supposed to be:

    [includes]
    [symbol]yourpackage.YourClass[/symbol]
    [symbol]yourpackage.YourOtherClass[/symbol]>
    [/include]

    Note that the node is not a child of [compiler] the node.

    Of course, substitute ‘[‘ brackets with the html-style tag ones, as you would use in your xml coonfig file.

    Harold Brenes

    9 May 09 at 4:20 pm

  29. senocular to the rescue! For me what this did was allow me to create a bunch of “filter classes” that I can apply and basically abstract the look of button classes away from their functionality, and some member of our team can manage the filter classes independently of the button class, except for registering the variables.

    Suggestion for Adobe is simply adding a switch to the .* wildcard like myClasses.*-ForceAll or something. Then we, the coders could decide instead of Adobe deciding for us whether or not to have classes in our code, although that would clearly pave the way for some pretty sloppy stuff and I can see why they would be leery as flash already gets a bad rap because of crummy flash code out there.

    code handyman

    18 Nov 09 at 12:05 pm

  30. Great tip! Thank you! I used this to instantiate movie clips in an application that gets the names from XML. Since I have no idea how many backgrounds the designers may want.

    public function init(name:String):void {
    var ref:Class = getDefinitionByName(name) as Class;
    var background:MovieClip = new ref as MovieClip;
    addChild(background as DisplayObject);
    }

    gregbown

    28 Jan 10 at 5:31 pm

  31. How about to use the event handlers and item renders in the UI components added using reflection concept.

    Can we load UI based on a xml compleletly by this reflection alone with out writing any code for handlers and other stuffs.

    Thanks in advance,
    Veeru

    Veeru

    11 Mar 10 at 1:53 am

  32. If your referencing a class using a string you must include the package name in that String. So if you packages is called com then

    var stringTest:String = “com.” + theStringForTheClass;

    var ref:Class = getDefinitionByName(stringTest) as Class;

    var test = new ref();

    Richard Eastbury

    22 Mar 10 at 9:14 am

  33. badass code!

    this ‘getDefinitionByName’ method literally saved me hours of repetitive code writing time, I just created one custom function that retrieved all the different class names and pass them right through!

    thanks!

    Hank

    22 Apr 10 at 1:41 pm

  34. Can i can give properties and methods to a targetpath?
    like [object Stage].[object MainTimeline].[objct movieclip].textfield…

    Akhil

    11 Jan 11 at 1:29 am

  35. All the solutions provided to the getDefinitionByName() issue involves the name of the target class. In case that you are developing a module, that’s going to by use by another aplication who is only going to tell you the name (or adress) oh the class, and therefore, the module doesn’t know the class. The only thing it can count on is the complete name of the class. There are any solution???

    Sorry about my english

    Mírmiken

    24 Jan 11 at 10:22 am

  36. The solution for custom class is something like this ->

    registerType(path.to.MyClass);
    var myClass:Class = getDefinitionByName(“MyClass”);

    function registerType(clazz:Class):void
    {
    // NOP – passing it is enough for it to be linked into the SWF.
    }

    Rudolfs

    13 Jun 11 at 7:35 am

Leave a Reply