New Apex Type Methods in Summer ’12

The recent fog in San Francisco can only mean one thing. It’s summer time! Specifically, it’s Summer ’12 release time. The next release of has already started rolling out to Sandbox Orgs, and is scheduled to roll out to Production Orgs in June. To get a sneak peek at some of the exciting new Developer features in the Summer ’12 release, you can register for the preview webinar that Pat and I are hosting on Wednesday (5/16).

Today, I want to highlight an important new addition to Apex that is easy to miss when perusing the Summer ’12 release notes – the addition of ‘getName’ and ‘newInstance’ methods to the Type system class. These new methods now allow you to instantiate Apex classes at runtime with just the String name of the class. No longer do you have to specify the type of class you want instantiated at compile time (e.g. MyClass newObj = new MyClass();). You can instead do something like this:

Type t = Type.forName('MyClass');
MyClass newObj = (MyClass)t.newInstance();

Experienced Java developers will recognize this as the start of supporting Reflection in the platform. Though Apex does not fully support all the features typically associated with Reflection yet, the ‘Type.newInstance’ method is an important step in that direction. Lets take a specific use case and walk through the how and why of this new Apex feature.

Imagine that you’re an ISV partner that has created a Managed Package on the platform (for listing on the AppExchange) to validate US Zip Codes for all Contact records added or updated in a Salesforce Org. Let say that your default implementation of this zip code validation checks for a valid 10 character zip code (e.g. ‘94105-1234’). Some of your package subscribers might however wish to customize the validation logic by for example checking for a 5 digit zip instead. Since subscribers are prevented from viewing the code included in a Managed Package (for protecting the ISV’s IP), its not simply a matter of modifying the Apex logic included in the package. The new Type methods offer an elegant solution by allowing subscribers to author their own zip code validation and then having your package dynamically detect and instantiate that ‘override’ at runtime. Lets walk through the package design.

The first piece of the puzzle is to define a simple interface that all zip code validation scripts need to implement.

global interface ValidateZipCode {

    boolean isValidUSZip(String zip);


Next, lets say that your package includes a ‘default’ implementation that checks for a 10 character zip code.

global class ValidateZipCodeDefaultImpl implements ValidateZipCode {
    global boolean isValidUSZip(String zip){
        //Check for a valid 10 character zip code
        //and return true or false as appropriate

Now say that one of your package subscribers wishes to implement a different validation logic. All they have to do, is to author a different implementation class. Something like

global class ValidateZipCodeMyCustomImpl implements ValidateZipCode {
    global boolean isValidUSZip(String zip){
        //Check for a valid 5 digit zip code and return true or false as appropriate

Now comes the fun part. In order to pick the appropriate zip code validator, I’ve implemented the classic Factory design pattern.

global class ZipCodeValidatorFactory {
    public static ValidateZipCode getValidatorInstance(){
        String defaultZipCodeValidationClass =
        String zipCodeValidationClass;

        Zip_Code_Custom_Impl__c settings =
               Zip_Code_Custom_Impl__c.getInstance('Zip Code Validation');

        if (settings != null && settings.Zip_Code_Validation_Class__c != null) {
            zipCodeValidationClass = settings.Zip_Code_Validation_Class__c;
        else {
            zipCodeValidationClass = defaultZipCodeValidationClass;

        Type t = Type.forName(zipCodeValidationClass);
        ValidateZipCode zipCodeValidator = (ValidateZipCode)t.newInstance();
        return zipCodeValidator;

By default, this factory class returns the default zip code validator class (ValidateZipCodeDefaultImpl) included in my Managed Package. However, subscribers can specify an ‘override’ by populating a Custom Setting (Zip_Code_Custom_Impl__c) with the name of the Apex class that implements the ValidateZipCode interface per their specific requirements. In the example above, the subscriber would set this Custom Setting to ‘ValidateZipCodeMyCustomImpl’. In my Factory class above, I can dynamically instantiate the correct zip code validator by using the ‘newInstance’ method (line 18).

The final piece of the puzzle is how I use the above Factory class to validate Contact zip codes. Here is the trigger code for that.

trigger CheckZipCodeTrigger on Contact (before insert, before update) {

    ValidateZipCode zipCodeValidator = ZipCodeValidatorFactory.getValidatorInstance();

    for (Contact c:
        if (c.MailingPostalCode != null && !zipCodeValidator.isValidUSZip(c.MailingPostalCode))
            c.addError('Invalid Zip Code');

Hopefully the example above has helped illustrate the power of the new Type methods in Summer ’12. If you have another interesting use case for ‘Type.newInstance’, please comment on the post and share it with the community.

tagged , , , Bookmark the permalink. Trackbacks are closed, but you can post a comment.
  • Nice simple example that shows how this new feature can be utilized. Thanks!

  • no exactly the same use case as above but you might want to check out Email2Apex. I created it to chain Batch jobs, but in general it can instantiate apex classes incl. parameters. ., still on API 23 but I’m going to update it soon.

  • Abhinav Gupta

    Good post Sandeep, it reminds me all of those classic Java days 🙂

  • Just tried to use the Type system class, but it doesn’t help me out.
    I’m trying to dynamically schedule a class like this:
    String className = ‘MySchedulableClass’;
    Type t = Type.forName(this.className);
    System.schedule(‘myJobName’, ‘myCronString’, t.newInstance());

    The schedule method doesn’t like this and my class will not save. Only when I cast the result to MySchedulableClass the class saves. But then my class isn’t dynamic anymore and I need to modify my class each time I add a schedulable class.

    As I look at your example, I see the same. Surely you dynamically instantiate your class, but you still need to cast it. Can you tell me the advantage over just instantiating the class like:
    MySchedulableClass cls = new MySchedulableClass();

    Kind regards!

    • Meant to reply to you directly but the answer to this is in my above comment.

    • Ronald, you’re not casting it as anything other than Type. Do you have a superclass or interface that you can cast it as? In the example he cast it as the interface “ValidateZipCode”. If you have a reason to dynamically schedule more than one job that is similar then you could create an interface that describes them both with a common interface.

  • Ronald, you would want to cast your t.newInstance() to the Schedulable interface

    System.schedule(‘myJobName’, ‘myCronString’, (Schedulable) t.newInstance());

  • Kevin actually made a better point, since it’s scheduled you can just cast to the interface used for schedulable classes. Completely forgot they use that interface already 🙂

  • Great post! nice to see Reflection finds a place in #apex.

  • Very interesting!

  • Really nice feature. Effectively adds “black box plug-in” functionality to apps. I wonder if this would work with add-on’s to a managed package, such as a separately purchased option.

  • Note that there is a known issue related to this that can prevent a managed package from finding the subscribing Orgs local class.

    Type.forName(String) in managed package does not resolve local apex
    class –

    • Anonymous

      Daniel – that is indeed a known issue, and the link you posted also contains a workaround for those affected by this. Thanks for posting.

  • Jason Venable

    With regards to managed packages and implementing the interface on to a subscriber defined class, does this need to reference the namespace of the interface?

  • Antoine Magnier


    thanks for this great idea/article.

    I used it in one of my SF ISV / managed package project. Maybe you can add one detail : If the factory needs to load a custom instance implementing the interface you need to use Type.forName with two arguments : first argument is namespace so put an empty string & the second one is the name of the implemenation class.

    If you use only one argument the factory will not succeed in loading the custom class in one subscriber org.


    Antoine from France

  • Shmuel Kamensky

    Is this in Salesforce documentation anywhere (not including release notes)?