Apex – When to Use Static Variables in Apex Controller

I have been looking into the documentation but could not get clear picture of benefit of using Static variables in Apex controller.

Apex documentation says that static variables are not transmitted as part of the view state

enter image description here

I created a simple example to test this and static variable seem to be transmitted to the server as part of the view state(even though it is not showing up in the viewstate tool) otherwise in the below example it should always come back as 10 from the server for every invocation of actionFunction(controller method someMethod) instead it comes back as 10 multiplied by the input value and results in same behavior as non-static variable.

Here is the code:

ExampleVFPage:

<apex:page showHeader="false" sidebar="false" controller="ExampleVFController">
    <apex:form id="main-form-id">
        <apex:outputLabel for="sv-id" value="Static Variable"></apex:outputLabel> 
        <apex:inputText id="sv-id" value="{!staticOne}"></apex:inputText>
        <apex:outputLabel for="nsv-id" value="Non Static Variable"></apex:outputLabel> 
        <apex:inputText id="nsv-id" value="{!nonStaticOne}"></apex:inputText>
        <a href="#" onclick="someMethodAF();">Click here</a>
        <apex:actionFunction name="someMethodAF" 
                                action="{!someMethod}" 
                                rerender="main-form-id"></apex:actionFunction>
    </apex:form>

</apex:page>

ExampleVFController:

public without sharing class ExampleVFController {

    public static Integer staticOne;
    public Integer nonStaticOne;

    public Integer getNonStaticOne(){
        if(nonStaticOne == NULL){
            return 10;
        }else{
            return nonStaticOne * 10;   
        }
    }

    public void setNonStaticOne(Integer x){
        nonStaticOne = x;
    }

    public static Integer getStaticOne(){
        if(staticOne == NULL){
            return 10;
        }else{
            return staticOne * 10;  
        }
    }

    public static void setStaticOne(Integer x){
        staticOne = x;
    }

    public PageReference someMethod(){
        return NULL;
    } 
}

Here is the output of the above code (sorry for bad quality):

enter image description here

Can somebody explain with the help of an example?

Note: I looked at this blog Static variables in visualforce but still could not understand.

Best Answer

tl;dr Use static or transient modifiers on values bound to input fields to reduce view state size, which avoids the 135kb governor limit for view state size, and generally causes the page to load faster because of the reduction in bandwidth usage.


The controller can get information in two ways: from the view state, and from the form data posted to the server. When you use a get/set method bound to an input element (even a hidden one), you don't need to store the variable in the view state. Otherwise, you do.

Consider the following code:

public class MyController {
  static Integer someValue;
  public MyController() {
    someValue = 1;
  }
  public void incrementCounter() {
    someValue++;
  }
}

If you have a page that has the following code:

<apex:commandButton action="{!incrementCounter}" value="Count!" />

You'd get a System.NullPointerException. However, if you wanted to have the page transmit the previous value, you could do so with the following changes:

public class MyController {
  public static Integer someValue { get; set; }
  public MyController() {
    someValue = 1;
  }
  public void incrementCounter() {
    someValue++;
  }
}

<apex:inputHidden value="{!someValue}" />
<apex:commandButton action="{!incrementCounter}" value="Count!" />

This code transmits someValue back and forth correctly, yet doesn't use view state.

To use view state, of course, you don't need to bind the value:

public class MyController {
  Integer someValue;
  public MyController() {
    someValue = 1;
  }
  public void incrementCounter() {
    someValue++;
  }
}

<apex:commandButton action="{!incrementCounter}" value="Count!" />

You can use static and transient in pretty much the same manner, except for some subtle differences. For example, if you wanted to use an extension class, you could use a static variable to communicate across different extensions, but you can't generally communicate across extensions using transient variables, since you need a reference to the extension's instance to get at non-static variables.

When designing pages, try to make sure that variables that are needed for a particular action are bound to an input field, and you can then make them transient to reduce view state size, which has performance benefits. A non-static, non-transient variable also set via a setter are effectively transmitted twice, which increases the loading time of a page because of the increased bandwidth and processing time needed to handle this situation.

In both of the examples above, they use approximately the same amount of bandwidth, while using public Integer someValue { get; set; } ... <apex:inputHidden value="{!someValue}" /> would use more bandwidth than either option.

Related Topic