11

I've created an interface within a managed package that installers can implement (much like the example here and Making your managed package extensible with Apex Plugins). Clients can then configure their class name in a custom setting and I invoke it as required.

Given just the class name as a string, how can I determine if the class it represents implements my interface?

Do I need to construct an instance from the Type so I can use instanceOf?

string className = 'someCustomClientClass';
Type t = Type.forName(className);
object testInstance = t.newInstance();
System.assert(testInstance instanceOf SomeClass.SomeInterface);

I guess this will work (with some additional checks that the type actually exists), but I'd prefer to just rely on the Type object rather than creating an instance and invoking whatever their constructor does.

2 Answers 2

9

Unlike Java, where the “Class“ can be constructed and checked for inheritance, the Type in Apex is fairly limited. One of the few operations it permits is instantiation as an Object of the Type.

The instanceof operator applies only to Object Instances, which would imply that the Type will have to be instantiated to check for inheritance.

(An alternative to instanceof might be attempting to cast it to the interface and handling the 'CastException')

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_methods_system_type.htm

Whilst I understand your intention to avoid loading any expensive construction logic, I'm guessing you will have to construct the classes for purposes of the actual callback.

1
  • 1
    I suspect you are right and my only option is to create an object and then use instanceOf or a cast. I'll leave this open for a bit to see if there are any other ideas before accepting. Thanks. Nov 1, 2012 at 22:43
8

There are two ways to accomplish this.

Query the ApexTypeImplementor Object

The Spring '22 release made the ApexTypeImplementor object available via SOQL - Find Which Apex Classes Implement an Interface.

A SOQL query can be used to find/verify that a given class implements a given interface.

List<ApexTypeImplementor> interfaceImpls = [
        SELECT ClassName, ClassNamespacePrefix
        FROM ApexTypeImplementor 
        WHERE InterfaceName = 'SomeInterface' and IsConcrete=true];

Documentation: ApexTypeImplementor (Object Reference)


Use the Type.isAssignableFrom() method

The Winter '20 release included the System.Type.isAssignableFrom(sourceType) method.

This avoids the need to create an actual instance of a class type to determine if it is assignable to another type.

String interfaceName      = 'IAccountService';
String implementationName = 'AccountServiceImpl';

Type interfaceType        = Type.forName(interfaceName);
Type implementationType   = Type.forName(implementationName);

Assert.isTrue(interfaceType.isAssignableFrom(implementationType));

Documentation: Type Class (Apex Reference Guide)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .