8

The Type class provides a way to dynamically instantiate a class based on a String name, so we can access member variables and instance methods. Is there a way to access static methods using this same mechanism?

What I'd like to do:

global interface Vehicle {
  Long getMaxSpeed();
  String getType();
  // added to sample, not possible
  static String getSomething();
}

global class VehicleImpl implements Vehicle {
  global Long getMaxSpeed() { return 100; }   
  global String getType() { return 'Sedan'; }
  // added to sample
  global static String getSomething() { return 'Something'; }
}

public class CustomerImplInvocationClass {
    public static void invokeCustomImpl() {
        // Get the class name from a custom setting.
        // This class implements the Vehicle interface.
        CustomImplementation__c cs = CustomImplementation__c.getInstance('Vehicle');

        // Get the Type corresponding to the class name
        Type t = Type.forName(cs.className__c);

        // Instantiate the type.
        // The type of the instantiated object 
        //   is the interface.
        Vehicle v = (Vehicle)t.newInstance();

        // Call the methods that have a custom implementation
        System.debug('Max speed: ' + v.getMaxSpeed());
        System.debug('Vehicle type: ' + v.getType());       
        // added
        System.debug('Something?: ' + t.getSomething());       
    }
}
6

3 Answers 3

7

Nope, at time of writing, the Type class can't do that.

The Type class can instantiate a class based on a string...and that's about it. Yes, there are a few other methods, but I've never come across a situation where I've actually used anything other than Type.forName() and Type.newInstance().

About the closest you'd be able to get is to have a public, non-static method in your target class (or any class, really) that calls your class's static method. I've personally used something close to this in the trigger framework I developed for my company (I retrieve a static class variable, rather than call a static method).

I can't quite put my finger on it, but having a public method that calls a class's static method feels like it defeats the purpose of having a static method.

4
  • 2
    The remaining methods are actually useless, although it does implement the methods that allows Type to be used in a Set (equals and hashCode), which you could theoretically use for caching ... something.
    – sfdcfox
    Aug 2, 2016 at 19:44
  • Also, mention this idea. More votes is better!
    – sfdcfox
    Aug 2, 2016 at 19:49
  • @sfdcfox That might be useful in a lazy factory...maybe. At that point though, it's probably better to just cache object instances by the string name that you'd already have.
    – Derek F
    Aug 2, 2016 at 19:53
  • Accepted your answer. This is the approach I started a couple hours ago, was hoping for something better.
    – Ray Dehler
    Aug 2, 2016 at 20:35
1

The OP was very close, there is a 'feature' in Apex that allows static methods to fulfil the contract of an interface, so this works, although it really really shouldn't.

public class Foo implements Bar {
    
    public interface Bar {
        void doSomething();
    }
    
    public static void doSomething() {
        System.debug('Hello');
    }
    
    public static void callIt() {
        Bar iBar = (Bar)Type.forName('Foo').newInstance();
        iBar.doSomething();
    }
}

Ref: ChuckJonas/wtfapex

2
  • I'm getting the error: Static method cannot be referenced from a non static context. Very close though.
    – muchavie
    Aug 7, 2021 at 23:04
  • @muchavie How did you test that, could be they have changed behaviour somewhere but the code as written is deploying and running for me without error. Aug 9, 2021 at 18:19
0

I was just researching this myself. I created a unlocked package without org dependency. Rather than pulling in all the classes just call a static method, I was trying to determine a way to call the static method using reflection of some sort.

So far the answer seems to be no, I simply cannot do that.

1
  • I'm in the same boat. The only way around this I can see to to avoid static method and public enums if you want to build a loosely coupled interface.
    – muchavie
    Aug 21, 2021 at 11:47

You must log in to answer this question.

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