[SalesForce] Question About Static Methods

I'm new to Apex and development in general…

So, I'm playing around coding and doing some badges in Trailhead.

I created a small piece of code, as below, and have no actual use:

public class GenderIdentifier {
    public void DetermineGender(String Gender){        
        if (Gender == 'Man'){
            Gender = 'Male';    
        } else {
            Gender = 'Female';
        }
      
    }
}

If I make the method 'non-static' it works, and I can see it working fine executing as a anonymous block.

If I make it static, I can't execute the anonymous block, as I get an Error like:

Non static method cannot be referenced from a static context: void GenderIdentifier.DetermineGender(String)

What am I doing wrong? It would make sense to have a method like this as Static. I think I misunderstood the concept of static methods.

Best Answer

Something that is static is "outside" of instance storage. In other words, it's a shared element across all copies of a class. For example, given this class:

 public class MyClass {
   public static Integer number;
   public String value;
 }

Let's try some code:

 MyClass c1 = new MyClass(), c2 = new MyClass();
 c1.value = 'Hello';
 c2.value = 'World';
 MyClass.number = 42;

The memory would look something like this:

    Static         Instances
+--------------+-----------------+
|              | value: 'Hello'  |
| number: 42   +-----------------+
|              | value: 'World'  |
+--------------+-----------------+

The number 42 is accessible to all copies of MyClass, as well as outside the class (in this case, because it's public). Note that there's only one box for the static variable; if you put a new value in there, the old one is kicked out. There's only ever one copy of number, no matter how many instances exist. Contrariwise, the instance variables only exist when there are instances, and each instance holds one copy of the variable, which may all be independently set.

Similarly, static methods operate the same way; there is only one "copy" of the method in memory. It cannot directly access any instance, because it is outside all instances. Instance methods are just the opposite; they require an instance of MyClass and cannot be called outside this context.

As a side effect, static methods can be called without using the new keyword to create an instance. This is useful for convenience or utility methods that do not manipulate instance data. You could call these global variables and methods.

Instance methods (those missing the static keyword) can only be called after an instance of the class is created. They should be used when there is an instance of the class to differentiate data between multiple copies of a class.

So, if you're curious as to which one you should use, simply ask yourself "does this method operate on a single instance of data?" If so, it must not be static, otherwise it can be static. There's traditionally different uses for static versus instance methods and variables.

Web service, REST, future, Remote Action, and Lightning Controller methods are all static. They operate on the global copy of the class they are in. Visualforce controllers and extensions, SOAP/WSDL callouts, Schedulable, Batchable, Queueable, Iterables, Comparables, Messaging.InboundEmailHandler, and other types of classes that can have multiple, concurrent data are not static.

The two main differences for static versus instance methods that you need to know are: static methods can be called from instance methods, but instance methods cannot be directly called from static methods (you must pass in an instance), and some specialized features (many examples thereof listed in the previous paragraph) require one type of method in order to work (you can't substitute static for instance or vice versa).

Buried somewhere in this answer is what you're asking for: does it make sense to have this sort of method be static? Yes; the method does not modify instance data, so it is classified as a utility method. It makes sense to have this method be static, just like String.isBlank or Messaging.sendEmail. You don't need an instance of the class for this method to succeed, so there's strictly no reason you should necessarily make it an instance method, because you're simply wasting keystrokes and CPU time that way.

Note that Execute Anonymous is slightly weird in how you execute Apex; as far as Execute Anonymous goes, you could have written:

public void DetermineGender(String Gender){        
    if (Gender == 'Man'){
        Gender = 'Male';    
    } else {
        Gender = 'Female';
    }
}
System.debug(DetermineGender('Man'));

Because Execute Anonymous invisibly wraps your entire block is an anonymous (unnamed) class. This has some interesting side effects with regards to compilation. I recommend using actual classes when possible, as the rules for compilation are more "normal" compared to Execute Anonymous scripts.

Related Topic