Hot answers tagged

17

Your strategy will work, but your constructor must contain no parameters, and the same goes for your newInstance() call. You pass the name of the Type you want to construct into the Type.forName method. Type customType = Type.forName('SomeClass'); SomeClass instance = (SomeClass)customType.newInstance(); You probably will want to implement an interface ...


13

The Platform Event feature was introduced very recently. Any time you are making use of such a new feature, make sure you set the API Version to the most up to date value available.


12

If you do have a need to pass parameters to the dynamically created class, a way to do that is to create the class by using JSON.deserialize: Type t = Type.forName('Process'); Process p = (Process) JSON.deserialize('{}', t); so that if the class has e.g. fields x and y: public virtual class Process { Integer x; String y; } you can set values in ...


8

You can still support concrete types with getTypeName by using the Type.forName method. Set<Type> whilelist = new Set<Type> { DmlException.class, ListException.class }; try { // do stuff } catch (Exception pokemon) { if (!whitelist.contains(Type.forName(pokemon.getTypeName())) { throw pokemon; } // actual error ...


7

It looks to me that this FORMAT() documentation fails to mention that the formatted value can only be obtained using a get of the alias. This produces the expected result for the formatted values and confirms that the type returned by FORMAT is String: Contact c = [ select Name, FORMAT(Birthdate) bb, FORMAT(CreatedDate) cc from Contact ...


6

You can only check against concrete types. Dynamic type checking is not possible afaik. For concrete type checking, you are looking for the instanceof keyword: public Interface IWidget { void doSomething(); } public class Widget implements IWidget { public void doSomething() { } } public class SpecificWidget extends Widget implements IWidget { } Object ...


6

The Business Manager backend of the instances have color-coded headers: Sandbox = grey Development = green Staging = blue Production = red Additionally on the top left you can see the instance name written (above your site dropdown) Finally, you can usually tell by the hostname of the instance. Production, Staging, and Development all have the instance ...


6

There's not any way (at least, not that I know of) to completely take the recordTypeId out of the equation, but there is a way to use the record type's name to get at the appropriate Id. Specifically, the SObject's "describe" information, via the DescribeSObjectResult class provides several methods to get record type information. Probably the most common ...


6

Refer this documentation: Sharing a Record Using Apex Apex sharing reasons are defined on an object's detail page. Each Apex sharing reason has a label and a name: The label displays in the Reason column when viewing the sharing for a record in the user interface. This label allows users and administrators to understand the source of the sharing. The label ...


5

You have a variable named 'Quote' in your variable scope. Do not do this. Quote quote = new Quote(); System.debug(quote.class); // compile-fail It works if you avoid naming variables after class names: Quote theQuote = new Quote(); System.debug(Quote.class); // outputs Quote You can still refer to it correctly if you use the Schema namespace, though: ...


5

The structure of your string payload does in fact clearly indicate a List structure, as it starts with a square bracket ([). You have a List<Map<String, Object>>. However, you have to deserialize into List<Object> then cast afterward. List<Object> data = (List<Object>)JSON.deserializeUntyped(payload); for (Object datum : data) {...


5

Triggers are not classes, and you shouldn't reference them like this. You should create a separate class to store your static variable, and then reference this class in both your controller and trigger.


5

This is expected behavior. It is strongly recommended that you do not name classes, interfaces, enums, or variables after built-in values, as it can cause compilation errors. Always use names that do not conflict with existing data types. For more information, see Namespace, Class, and Variable Name Precedence, notably: The parser first assumes that ...


5

Here is one approach I've come up with using Type and newInstance(). As anonymous apex: Account acc = new Account(Name='Test'); insert acc; List<sObject> accounts = new List<Account>(); accounts.add(acc); Schema.SObjectType listObjType = accounts.getSObjectType(); //Instantiate a Map based on the input list sObject type. Type mapType = Type....


4

Solved that To test if a variable is a list regardless of the type of its elements obj instanceof List<Object>


4

You cannot generically call a non-no-argument constructor. While other object-oriented languages have methods for doing this, Apex Code does not have any support for this.


4

It's mostly "working as designed." Logically, there's no problem saying this: SObject[] c = new Contact[0]; This allows you to work on any type of record without knowing in advance that they're contacts. It's convenient to do that. In fact, that's the primary reason why this is supported. It is expected that you'll check the data type of each record ...


4

This issue is due to the case insensitive nature of Apex. You can reproduce it with any class name. Once you declare an instance with the same name as the class, the compiler tries to dereference the instance instead. MyClass myClass = new MyClass(); Type myType = MyClass.class; // compile fail // last reference to MyClass points to instance Note that you ...


4

You can use the name directly without a describe call: Object__c record = new Object__c(Name='Demo', RecordType=new RecordType(Name='SomeType')); Note that this technique only works if the record type game is globally unique in your org across all sObject types. Otherwise, you can, and should, use a describe call to get the Id dynamically, as noted in the ...


4

Apex, like Java and other Object-Oriented Languages before it, are strongly-typed languages. This means that the compiler can check if an object is compatible with an assignment or operation before the code runs. This reduces the odds of deploying code that has no chance of ever working correctly. For example, you can't write: Integer i = 5; String s = i; ...


3

Just to test out... I created a sharing reason for a test object and ran the following line in Developer Console: System.debug(Schema.MyObj__Share.rowCause.MyCause__c instanceof String); I got back the error Operation instanceof is always true since an instance of String is always an instance of String. So that tells me it returns a String and not some ...


3

In Apex Code, a class in a managed package has a "namespace." This is a prefix used by the platform to allow a managed package to have the same class name (and other things, like objects, fields, triggers, etc) as a class in your org. To use such a class in Apex, you need to include its namespace prefix. You can find this detail on the class' detail page, or ...


3

It's doable with an abstract base class as shown below. public abstract class CustomException extends System.Exception { } Implementing exception classes public class AException extends CustomException { } public class BException extends CustomException { } This test proves that it works @IsTest private class CustomException_Test { @IsTest ...


3

Your JSON.deserialize will (probably) set the fields but not via the constructor you have the System.debug in. (Constructors can have an arbitrary signature but the field names are effectively a fixed signature.)


3

That's expected, as you can't directly access public classes in that manner. You'll want a global class you can call. To avoid exposing implementation details, the method itself can be public. You probably want to just create a Factory instead. At a very basic level... global class Factory implements Callable { public Object call(String action, Map<...


3

The problem is an invalid (or null) return on the Type class using forName. You need to validate the return of forName before looking to cast into an SObjectType String myString = 'InvalidClass'; Type classType = Type.forName(myString); SObjectType sObjType; if (classType != null) { sObjType = ((SObject) classType.newInstance()).getSObjectType(); }


3

You need to cast your variable type. The class that implements that interface should be cast to that interface, so you can access its methods: IMyInterface instance = (IMyInterface) Type.forName('Myclass'); instance.someMethod1();


3

We don't have that level of reflection in Apex. You cannot inherently tell that an Object is a user-defined class. You can tell that: public class FakeClass {} Object classObj = new FakeClass(); Object fakeClassType = FakeClass.class; System.assert(classObj instanceof FakeClass); // true // System.assert(classObj instanceof Object); // trivially true, ...


2

Here is my Utility class that does this with props to @sfdcfox // ------------------------------------------------------ // getIdSetFromField : gets a set of Ids from a list of sobjects in <field> // ------------------------------------------------------ public static Set<ID> getIdSetFromField(SObject[] records, SObjectField fieldname) { ...


2

At this time, Apex doesn't have much in the way of introspection/reflection. That getType() method that you found looks like the best solution we currently have available to us.


Only top voted, non community-wiki answers of a minimum length are eligible