Can anyone please provide some detailed description about How to use the "Type" reserved keyword of salesforce ?
-
3The Type Class can be used for limited reflection and dynamic instantiation... the docs are great.– Matt and NeilCommented Jan 17, 2014 at 13:58
-
2@user320 You should post that as the answer. That is essentially what this user is looking for. You may want to add a bit more detail, but as you noted, Salesforce has great documentation.– Jesse AltmanCommented Jan 17, 2014 at 14:01
-
1Agreed. The question is not very detailed or specific, so pointing them to documentation with a link seems adequate in this case.– Chris DuncombeCommented Jan 17, 2014 at 14:35
-
1Can you please try to use correct tags related to the subject of your question ? This will help you get answers quicker! Also: trying to shape your question around specific problems makes it easier to provide answers. Questions that are too broad or unclear do get closed.– Samuel De RyckeCommented Jan 17, 2014 at 14:46
-
1Thanks All. Actually I saw use of this into an apex class and tried to find out the exact meaning but didn't get anything. So I posted this question here. @user320 thanks a lot for the link.– S.SharmaCommented Jan 17, 2014 at 17:17
2 Answers
The System.Type class represents a reference to a class. There are two basic purposes for using System.Type.
Dynamically Accessing Classes
In this question's answer, I show how you can dynamically select a function to invoke by calling one of four operations from a map. First, you create an interface or abstract class, then you create subclasses/implementations, followed by mapping them out somehow, and finally invoking them through the common interface or parent class methods.
Here's the controller that uses the interface-style method:
public class calculatorController {
interface operation {
decimal execute(decimal op1, decimal op2);
}
class Add implements operation {
public decimal execute(decimal op1, decimal op2) { return op1 + op2; }
}
class Subtract implements operation {
public decimal execute(decimal op1, decimal op2) { return op1 - op2; }
}
class Multiply implements operation {
public decimal execute(decimal op1, decimal op2) { return op1 * op2; }
}
class Divide implements operation {
public decimal execute(decimal op1, decimal op2) { return op1 / op2; }
}
public selectoption[] getoperators() {
return new SelectOption[] {
new SelectOption('add', '+'),
new SelectOption('sub', '-'),
new SelectOption('mul', '*'),
new SelectOption('div', '/')
};
}
public decimal op1 { get; set; }
public decimal op2 { get; set; }
public string op { get; set; }
public decimal result { get; set; }
public void calculate() {
map<string, type> ops = new map<string, type> {
'add' => add.class,
'sub' => subtract.class,
'mul' => multiply.class,
'div' => divide.class
};
try {
operation o = (operation)ops.get(op).newinstance();
result = o.execute(op1, op2);
} catch(exception e) {
result = null;
apexpages.addmessages(e);
}
}
}
Dynamic Code Injection
By using Type.forName
, you can invoke logic that isn't included in the original package, perhaps as a detection routine for extensions, or as a facility for after-market classes that might be introduced by the installed organization.
I've only rarely seen this usage, but it could be used to provide a hook into trigger logic, or page logic, etc. For example, a managed package trigger might look like this:
trigger CaseTrigger on Case (before insert, after insert, before update, after update, before delete, after delete, after undelete) {
try {
((CaseExtension)Type.forName(null, 'CaseTriggerExtension')).handleTrigger();
} catch(TriggerException e) {
// Handle exceptons thrown by third party code
} catch(Exception e) {
// Ignore other exceptions
}
// Perform your managed code here
}
In this case, the system tries to call a class named CaseTriggerExtension
in the default namespace that conforms to a global interface named CaseExtension
, which has a single method defined (handleTrigger
). If there is no such class, or it doesn't conform to the interface, or some uncaught exception occurs, the trigger carries on with other logic. Conversely, there is a global exception class called TriggerException
that extends Exception
, and CaseTriggerExtension
can throw a specific exception that can possibly interrupt or rollback the routine. Since it is a custom class, you could include a means to determine which records had the error, or return early to allow the system's automatic retry handler (if allOrNone is false) to restart the trigger.
The Type
class can be used for limited reflection and dynamic instantiation. Check out the documentation