Tuesday, February 19, 2013

static keyword in Java

Java allocates memory after instantiation a class, using new operator. But there is one exception to this rule, static keyword.

The static keyword is used with data and methods of the class:
  1. If you want to have only a single piece of storage for a particular field, regardless of how many objects of that class are created, or even if no objects are created.                                    
  2. If you need a method that isn't associated with any particular object.      
static members of the class are also referred to as class data ( and class methods) or in general class members. Class name is the preferred way to refer to static members of the class, though you can use objects as well. You can't apply static keyword to local variables.

 public class StaticDemo {  
      private static int count; // initialized to default value of int i.e. 0  
   
      public static int getCount() {  
           return count++;  
      }  
   
      public static void main(String[] args) {  
           System.out.println(" Count: " + StaticDemo.getCount());  
           StaticDemo sd = new StaticDemo();  
           System.out.println(" Count: " + sd.getCount());  
      }  
 }  
Output :
 Count: 0
 Count: 1

Note, the first call to method, getCount() is using Class name but the second call is through an instance of class. The output returned is consistent. This example proves a point that there is a single storage for static data.

It's debatable if static methods are Object Oriented as you call methods without creating objects. My suggestion, avoid using lots of static methods.

static Initialization and static block

Below 2 are one and same :
       private static int count = 10;  //static initialization

or

       private static int count;
       static{    //static block
          count=10;
       }      

And you can have multiple statements inside a static block.

Order of Execution

Below example demonstrate the order of invocation :

 public class StaticLoadDemo {  
      static {  
           System.out.println("Class StaticDemo loading...");  
      }  
   
      static final int c = 5; // static initialization  
      static int a;  
   
      static { // static block  
           a = c;  
           System.out.println("value :" + a);  
      }  
   
      StaticLoadDemo() {  
           System.out.println("Constructor");  
      }  
   
      public static void main(String[] args) {  
           new StaticLoadDemo();  
      }  
   
      static {  
           System.out.println("final static block");  
      }  
 }  
Output:
Class StaticDemo loading...
value :5
final static block
Constructor

Important Points:
  1. Static block/initialization gets invoked right after class gets loaded. The output of the above class confirms the same.
  2. Static block is called only once (during the lifetime)
  3. If StaticLoadDemo class extends a base class named as Base. Then static blocks of Base class will be invoked first,  followed by subsequent subclasses.
  4. Order of initialization is static first if they haven't been already initialized by previous object creation, and then non-static component.

Inheriting static component

static components are associated with the class and not the individual object. So if a method is static, it doesn't behave polymorphically.
 class Super {  
      public static void printHello() {  
           System.out.println(" hello --base class");  
      }  
 }  
   
 public class Derived extends Super {  
      public static void printHello() {  
           System.out.println(" hello --derived class");  
      }  
   
      public static void main(String[] args) {  
           Super s = new Derived();  
           s.printHello();  
      }  
 }  
Output:
hello--base class

Memory allocation and  de-allocation

static methods (in fact all methods), as well as static data, are stored in the PermGen section of the heap, since they are part of the reflection data (class related data, not instance related data). 
  1. static primitive variables are stored in PermGen (Permanent Generation) space.
  2. If static data references to an Object; then reference is stored on PermGen but the actual object gets stored in heap(young/old generation).
 static members get garbage collected only when class gets unloaded (details here).

---
do post your feedback !!!

2 comments: