function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
GeorgePGeorgeP 

Can I create a class from the value in a string?

Is it possible to create or instantiate a class of a type the is equal to the value of a String?    So something along these lines;

//Normal code
private MynewClass MyNewClass;
MyNewClass = new myNewClass();

// Is something like this possible instead?
private MynewClass MyNewClass;
String tempString = 'MyNewClass';
MyNewClass = new tempString();  //  ie somehow get the value of tempString' as the type of class to create.

cheers
George
Best Answer chosen by GeorgeP
Marek Kosar_Marek Kosar_
Hi George,

There is Type class in apex, which could be helpful in your case, try something like:
private Object MyNewClass;
String tempString = 'MyNewClass';
Type t = Type.forName(tempString);
MyNewClass = = t.newInstance();

Marek

All Answers

GeorgePGeorgeP
Why can't we edit our questions for a short while after posting them??
myNewClass should be MyNewClass above.
Marek Kosar_Marek Kosar_
Hi George,

There is Type class in apex, which could be helpful in your case, try something like:
private Object MyNewClass;
String tempString = 'MyNewClass';
Type t = Type.forName(tempString);
MyNewClass = = t.newInstance();

Marek
This was selected as the best answer
GeorgePGeorgeP
Hi Marek

Here is my attempt:
private Object PricingClass;
String tempString = 'CuaBundledCSVProcessing';
Type t = Type.forName(tempString);
 PricingClass = new t.newInstance();

Its falling over on the last line, the error is: Invalid type: t.newInstance

any idea?
cheers
Marek Kosar_Marek Kosar_
remove NEW from the last line ;)
GeorgePGeorgeP
Thanks for that Marek, i need to get glasses :)
Next question though is how do i access a method of the class type that I have instantiated using this approach?
GeorgePGeorgeP
I ask that because if i code, using the above examples, PricingClass.getErrorNum()  where getErrorNum() is a method belonging to the class type being created, ie in this example the method CuaBundledCSVProcessing.getErrorNum(); exists however when i code  PricingClass.getErrorNum() i get the following error message:  "Method does not exist or incorrect signature: [Object].getErrorNum()"
Marek Kosar_Marek Kosar_
Hi george,

oh, I didn't realize that.. you still have to cast return value of .getInstance method to proper type:
String tempString = 'testWrapper';
Type t = Type.forName(tempString);

testWrapper tWrapper = (testWrapper)t.newInstance();
I'm not aware of any other way to do that, sorry :(
 
GeorgePGeorgeP
Ok, so if i still have to know when I'm using the testWrapper class then it kind of defeats the purpose of the excercise unfortunately. 

This was the code I was hoping to run:

// here the Pricing_class__c variable has the name of anyone of 4 classes that all have the same methods but do different things depending on the type //of contract they are for.
             Object PricingClass;
             List<Offer_Type_Of_Contract_Mapping__c> tocList = [Select Pricing_Class__c from Offer_Type_Of_Contract_Mapping__c
                                                                                                                              where Type_Of_Contract__c = :typeOfContract limit 1];
             Type classType = Type.forName(tocList.get(0).Pricing_Class__c);
             PricingClass = classType.newInstance();
             errorNum = PricingClass.getErrorNum();

Was hoping toprevent this sort of thing a bit later in the program:
                      if (typeOfContract == 'CUA Bundled') {
                          myList = CuaBundledPricing.validateData(csvRecordData, OppId, OppID_c, lineNum, errorNum);
                          errorNum = CuaBundledPricing.getErrorNum();
                          if (noErrors) noErrors = CuaBundledPricing.getNoErrors();
                          if (!acctnumberspresent) acctnumberspresent = CuaBundledPricing.getAcctNumbersPresent();
                       }

                      if (typeOfContract == 'CUA Unbundled') {
                          myList = CuaUnBundledPricing.validateData(csvRecordData, OppId, OppID_c, lineNum, errorNum);
                          errorNum = CuaUnBundledPricing.getErrorNum();
                          if (noErrors) noErrors = CuaUnBundledPricing.getNoErrors();
                          if (!acctnumberspresent) acctnumberspresent = CuaUnBundledPricing.getAcctNumbersPresent();
                       }

                   etc, ie repeat above code for each contract type that needs its own dedicated but similar class

oh, well, back to the drawing board!

cheers

 
GeorgePGeorgeP
Figured it out in the end, just have to have seperate methods creating the required class based on the String value & then had to cast the 'Object' class to the correct class whenever it was used.
Jon JardineJon Jardine
This is an old thread but it gave me the hints I needed to develop a working solution. The trick is to create a virtual parent class which defines the methods required, then create child classes with these same methods. As the methods are the same, even though you're instantiating the child class the signatures are the same so the object creation succeeds.
public virtual with sharing class ParentClass {
    public virtual String process(props) {
        return '';
    }
}

public with sharing class ChildClass extends ParentClass {
    public override String process(props) {
        return 'Content added from ChildClass.';
    }
}
// Test class instantiation from strings
String className = 'ChildClass';
Type t = Type.forName(className);
ParentClass parent = (ParentClass) t.newInstance();
String result = parent.process(props);