I read in salesforce documentation -

Static variables are only static within the scope of the request. They’re not static across the server, or across the entire organization.

Can any one explain what does it mean? If i take a scenario like below -

I have a class XX which has one static boolean variable state. Now i create 3 instances of class XX say A, B, C and set state = True in instance A.

Now what would happen if i see state value in object B and C. Will it be True OR False.

If True then what Static variables are only static within the scope of the request means?

Updated-

Thanks for such a intelligent answers. May you please answer below question as well?

Suppose i have class like below -

public with sharing class GlobalVariables 
{
    public static Boolean fireValidation = true;
}

I have after insert, before update trigger on object where i check following condition -

if(GlobalVariables.fireValidation) {
    // Fire some validations.
}

now there are two different code flows.

1) In first code flow like below i set this Global_Variables.PCFlag = false and update the record. will validations get fired? // As per my understading so far NO as fireValidation is set to false.

    if (some condition) {                                  
      GlobalVariables.fireValidation = false;
      // Update record.
      GlobalVariables.fireValidation = true;
}

2) In other code flow like below i don't set Global_Variables.PCFlag = false and save the record. will validations get fired? // I think validations will get fired as it will run in other context.

    if (some condition) {                                  
     // Update record.
    }

3) What will happen if at the same time user 1 is executing this trigger as per condition1, user 2 is also executing the same trigger? Do they overwrite each other's value? // I think they wouldn't as they will run in their own context.

  • static variables and methods are attributes only to the class and not to any instance of the class – Scott Pelak Sep 9 '13 at 22:32
up vote 10 down vote accepted

Understanding the execution context is very important to understand how 'static' works in apex. As Mohith pointed out static doesn't behave the way as it works in java/c#. An execution context is one which either initiated by a user (e.g. through visualforce page action or apex trigger) or could run on own (e.g. scheduler) and executes a sequence of events/code. A static variable retains the value only during this execution context.

To answer your question, the value of the variable 'state' will be retained and visible across all three classes named 'A', 'B' and 'C' only when these classes are instantiated in the same execution context. Let's say two different users access the same visual force page and perform an action - then we have two execution contexts here and the value of this variable 'state' will be different between the two different execution contexts. This is in contrast to java/c#, where once the static variable is initialized, the value of the static variable is same to all users. This link may help you to understand the execution context.

  • 1
    I really hate the "it doesn't work the way it works in Java/C#", because it does actually work the same way. If you run the same Java program five times, each program has its own copy of the static variable. They can't magically communicate with each other through this static variable. In that sense, static is right what it says on the tin: static within the current execution context. – sfdcfox Sep 9 '13 at 18:57
  • 1
    Yes, but in say a .Net web app a static variable would have the same value for different users if they're served by the same process. It is a flawed comparison, though, because even then, with web farms, different processes could have different values. – Mike Chale Sep 9 '13 at 19:04
  • In .NET if you have a static variable in ASP.NET code behind file and if multiple users are accessing the same page, then this static variable is shared. This is not the same behavior in apex and that is what I and Mohith are trying to point out. – Tech Matrix Sep 9 '13 at 19:14
  • The comment is still misleading. I've programmed in Java off and on for over a decade, and I've never had a "shared static" variable, nor would I expect my static variable to magically share itself across all instances of my application. – sfdcfox Sep 9 '13 at 19:21
  • Dug into that a bit more. Tomcat "re-uses" classes, so static variables can span a session. But, if one wrote a generic Java HTTP server that spawned a process for each connection, then the static variables would be isolated. Hence, the confusion. Java itself isn't the problem, it's the applied usage of Java in a specific context. – sfdcfox Sep 9 '13 at 19:26

Static variables do not belong to an instance of a class, they belong to the transaction's static memory area.

In your first example, given:

public class XX {
    public static boolean state = true;
}

You could write this code:

XX A = new XX(), B = new XX(), C = new XX();

But, you couldn't later call:

if(a.state) {
    // do this when true
}

Because state is not a member of A, but instead of the class XX.

Static values behave just like they do in desktop implementations of Java, C#, and other object-oriented languages that support static members. This means that when multiple users access the same code, simultaneously or at separate times, those static variables will be initialized each time using static initialization or static blocks provided, and will maintain isolated values for each transaction. However, each transaction only gets one copy of that value.

Some servers implement a means whereby static variables in languages such as Java, or C# behave as "server-shared" variables; in this case, it tends to be that the memory from each transaction isn't isolated. Apex Code doesn't behave like these server implementations of those languages, but instead like the desktop version of those languages-- each transaction gets its own unique copy of a static variable that acts independently of all others.

Given class XX as above, if users Alice and Bob both invoke an action that uses XX, the server memory looks like this:

Alice Transaction 1              Bob Transaction 2
XX.state = true                  XX.state = true

If, through the course of code, Alice's XX.state value is modified, the server memory might then look like:

Alice Transaction 1             Bob Transaction 2
XX.state = false                XX.state = true

Even though XX.state is static, it is not "server static" or "shared static." Each transaction gets its exactly one instance of XX.state. This behavior differs from Tomcat and other server implementations that use "static" to mean "across all instances."

Static variables are a developer's only defense against infinitely recursive triggers, such as:

trigger updateAccounts on Contact(after update) {
    // update accounts for those contacts
}

trigger updateContacts on Account(after update) {
    // update contacts for those accounts
}

Without a flag to stop recursion, these two triggers could infinitely call each other, and users wouldn't be able to save any accounts or contacts. Since static variables exist for an entire transaction, they're perfect for stopping this kind of recursion, or in general communicating across triggers.

However, if two users are trying to update the same record at the same time, one user may receive an error (either a row-locking error, or a record-has-been-modified error). The other user's save will complete successfully. Note that if two actions occur nearly instantaneously and both complete, then the most recent transaction wins. This has nothing to do with static variables, however. Their static variables still won't be shared, however.

  • Great explanation. Thanks for reply – Pramod Kumar Sep 10 '13 at 12:35

The meaning of static resource is not same as in Java .IF you define a static variable as True then for the whole context the static variable will remain true unless you explicitly make it false .

For the context lets assume you have a class A having static Boolean defined state and its accessed by User A and User B at same time in the web request.Assume in the flow of the context there is a point in the program where the Boolean state is made false now lets assume when program is executing the point is reached where the state is false before user B tried to access it and then static Boolean wont be set as false for User B unless it reaches point in context of user B.

So conclusion is static variables are limited to a single context and single web request.Each context is independent as far as static Boolean

  • That's actually how static variables work in Java. If I run the same program three times, they cannot share each other's static variables. – sfdcfox Sep 9 '13 at 18:58
  • Nope they have some memory.See Tech Matrix answer as well – Mohith Shrivastava Sep 9 '13 at 19:03
  • I just wrote code that proves otherwise, just to make sure I was sane. Program sleeps 10 seconds, then increments a static value and outputs value, repeats. I am running it in different cmd windows and they are counting independently. – sfdcfox Sep 9 '13 at 19:14
  • 1
    @sfdcfox dont know sir, but even i have extensively worked in java for years and used static variable where we need to maintain the variables across the server. The static variables will not be destroyed in java as soon as user session ends. These are created and destroyed when the server is started and shutdown. These memory for the static variables in java are allocated at the server startup. – Mukul Goel Sep 10 '13 at 9:49
  • 1
    --continued so that later these can be used from the static variable which is comparatively faster than loading it everytime in to some variable. But still if u insists i think complete reference for java is best source to confirm on the same. – Mukul Goel Sep 10 '13 at 9:56

Scope of the request mean:

Suppose a visualforce page initialised with class XX and If you set state = false for A in that scope all instances of class XX, B ,C will show state = false accessed from A. but if you open a same visual force page in next window/tab and check for the value it will be true (default). Also if you change that value to some other then in that case there will be no impact on visulaforce page opened in previous window/tab.

Static method/variables works only in pagecontext. As page change or initialise all static variable set to default state.

Reloading a page reset the context.

Update:

3) User one context is completely isolated form user two context. I have said previously by example if same visualforce page is opened in two tabs than both have there own context. So You are right. "both have their own context"

2) Validation will get fired as GlobalVariables.fireValidation = true (default) and it is isolated from context in 2) below.

1) Let's suppose you have hit a visual force page (as visual force visible a context has been created for that instance in which a controller class get initialised). In visualforce page you have a command button which insert a record and fire a trigger but before insert you have set GlobalVariables.fireValidation = false then that trigger will get false value in it.

if (GlobalVariables.fireValidation) { 

// false for `1)` and true for `2).

}    
  • This also applies in triggers, batch apex, scheduled apex, and everywhere else. – sfdcfox Sep 9 '13 at 19:00
  • I have added few more conditions in my question. It would be great if you can answer those as well. – Pramod Kumar Sep 10 '13 at 7:53
  • @PramodKumar updated my answer. – Ashwani Sep 10 '13 at 8:17

For me, the simplest way to decide if a method or variable should be static is to think about how you are going to use it. Static methods are those that don't depend on having an instance of the class you are concerned with. Therefore, they don't require having an instance of the class you are concerned with in existence for your method to work.

Another way to think about instance and static methods is what are the methods for? Instance methods answer questions about one particular instance of the class while static methods answer questions about the entire class.

Example 1: I want to make a card game, so I create a class called Card. Each card has a string called Suit and an integer called Rank. ... (more to come here) ...

Example 2: Consider the string class. (It's interesting to note that strings are not a primitive data type to Java.)

The valueof method is a static method. How can you tell? How you call it. Since static methods don't rely on an existing instance of the class at hand, you call the methods via the class itself.

integer myInt = 12;
string myInt_asAString = string.valueof(myInt);
// NOT LIKE THIS:  string myString = new string();
// (cont'd):       myString = myString.valueof(myInt);

Notice how you use the class name to call the method. Contrarily, Instance methods do require the existence of an instance of the class at hand -- the method does some calculation on the instance variables.

Example: Consider the left method of the string class: string myString = 'testing strings'; string theFirstFour = myString.left(4); // = 'test'

The output left instance method is computed from the string instance provided (in this case myString).


a good examples of a static method is a method to create test objects for your test methods. These methods are simple and don't need to know any "saved" data to compute the output. These methods are fixed (static).

@isTest class testObject{

    public static list<Account> account(integer numAccts){
        list<Account> returnList = new list<Account>();

        for(integer i=0;i<numAccts;i++){
            Account a = new Account();
            a.name = 'Test Account - '+string.valueof(i);
            // other fun stuff
            // ...
            returnList.add(a);    
        }

        return returnList;
    }//END account

}//END class 

And suppose you want to call the above method in your test code:

public class Account_test{

    private static testMethod void myAcctTest(){
        // create 12 test accounts
        list<Account> acctList = testObject.account(12);

        // other test code . . . 
    }//END myAcctTest

}//END class

Notice two things:

  1. testObject's static method account had no reliance on any testObject variable, i.e. the computation is "fixed" -- the computation relied solely on its inputs.
  2. How the account method was called: the class name + the method name: testObject.account( numberOfAccountsToCreate )

Lastly, static methods can only call static variables or other static methods.

  • thanks for the down vote! it surely inspires me to try to help!! – Scott Pelak Sep 10 '13 at 18:22

Your Answer

 
discard

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.