We have a bunch of custom objects, some of which implement a specific set of custom fields of the same type. (e.g., UniqueID, ExternalID, etc.). I want to be able to write one method that takes and object and works with these fields without knowing (or caring) which object type it is. I know it is easily doable in Java but not sure how Apex allows this.
So I want something like this:public static void updateID(SObject myObject){ myObject.uniqueID__c = myObject.externalID__c; }
Answer
Mechanics
You need to use the get
and put
methods. Each method supports both String
and SObjectField
as the parameter type:
// terse
myObject.put('UniqueId__c', myObject.get('ExternalId__c'));
// verbose
SObjectField fieldToGet = MyObject__c.ExternalId__c;
SObjectField fieldToPut = MyObject__c.UniqueId__c;
Object value = myObject.get(fieldToGet);
myObject.put(fieldToPut, value);
Best Practice
There are many different scenarios under which you may want to use the dynamic methods get
and put
. How do you decide whether to use String
or SObjectField
?
SObjectField
Pros
- Creates a hard-coded reference to the field.
- If you try to delete the referenced field or change its API Name, the UI will prevent you from doing so!
- In other words, this approach protects your code.
Cons
- Syntax is somewhat more verbose. If you are really crunching up against the character limit, this style of reference might use more than you need.
- There are probably better ways to shave characters.
- You cannot pass cross-object references, like if you wanted to reference
Account.Owner.Name
fromOpportunity
.- You cannot call
someOpportunity.get('Account.Owner.Name')
, but you can combinegetSObject
and some string parsing to achieve the desired result.
- You cannot call
String
Pros
- More terse syntax allows you to write the same code in fewer characters.
- Accepting this type as an input for your own method would allow you to support cross-object
get
calls (by incorporatinggetSObject
).
Cons
- Does not populate to the SymbolTable, meaning there is no programmatic connection anywhere between your code and the referenced field.
- Because there is no programmatic connection, the system. will allow the field to be deleted or renamed (barring other blocking dependencies).
- In other words, your code is vulnerable to configuration changes which might break it down the road.
Documentation
Both of the above are well covered in the Apex Developer Guide
documentation for the SObject
class. There are a few more signatures but you get the idea:
get(fieldName)
Returns the value for the field specified by fieldName, such as AccountNumber.Signature
public Object get(String fieldName)
Parameters
fieldName
Type: StringReturn Value
Type: ObjectUsage
For more information, see Dynamic SOQL.
put(fieldName, value)
Sets the value for the field specified by the field token Schema.sObjectField, such as, Schema.Account.AccountNumber and returns the previous value for the field.Signature
public Object put(Schema.SObjectField fieldName, Object value)
Parameters
fieldName
Type: Schema.SObjectFieldvalue
Type: ObjectReturn Value
Type: Object
Attribution
Source : Link , Question Author : Jorjani , Answer Author : Adrian Larson