Thursday, December 11, 2014

Java: Static class / static variable / static method / static block

http://www.geeksforgeeks.org/static-class-in-java/
http://www.geeksforgeeks.org/static-keyword-in-java/
http://www.geeksforgeeks.org/g-fact-79/

1. Static class in Java:
Can a class be static in Java ?
The answer is YES, we can have static class in java. In java, we have static instance variables as well as static methods and also static block. Classes can also be made static in Java.

Java allows us to define a class within another class. Such a class is called a nested class. The class which enclosed nested class is known as Outer class. In java, we can’t make Top level class static. Only nested classes can be static.

What are the differences between static and non-static nested classes? 
Following are major differences between static nested class and non-static nested class. Non-static nested class is also called Inner Class.
  • Nested static class doesn’t need reference of Outer class, but Non-static nested class or Inner class requires Outer class reference.
  • Inner class(or non-static nested class) can access both static and non-static members of Outer class. A static class cannot access non-static members of the Outer class. It can access only static members of Outer class.
  • An instance of Inner class cannot be created without an instance of outer class and an Inner class can reference data and methods defined in Outer class in which it nests, so we don’t need to pass reference of an object to the constructor of the Inner class. For this reason Inner classes can make program simple and concise.
Code example:
/* Java program to demonstrate how to implement static and non-static
   classes in a java program. */
class OuterClass{
   private static String msg = "GeeksForGeeks";
    
   // Static nested class
   public static class NestedStaticClass{
      
       // Only static members of Outer class is directly accessible in nested 
       // static class 
       public void printMessage() {
 
         // Try making 'message' a non-static variable, there will be 
         // compiler error  
         System.out.println("Message from nested static class: " + msg); 
       }
    }
    
    // non-static nested class - also called Inner class
    public class InnerClass{
        
       // Both static and non-static members of Outer class are accessible in 
       // this Inner class
       public void display(){
          System.out.println("Message from non-static nested class: "+ msg);
       }
    }
} 
class Main
{
    // How to create instance of static and non static nested class?
    public static void main(String args[]){
        
       // create instance of nested Static class
       OuterClass.NestedStaticClass printer = new OuterClass.NestedStaticClass();
        
       // call non static method of nested static class
       printer.printMessage();   
  
       // In order to create instance of Inner class we need an Outer class 
       // instance. Let us create Outer class instance for creating 
       // non-static nested class
       OuterClass outer = new OuterClass();        
       OuterClass.InnerClass inner  = outer.new InnerClass();
        
       // calling non-static method of Inner class
       inner.display();
        
       // we can also combine above steps in one step to create instance of 
       // Inner class
       OuterClass.InnerClass innerObject = new OuterClass().new InnerClass();
        
       // similarly we can now call Inner class method
       innerObject.display();
    }
}


2. Static data members
Static keyword is used for almost same purpose in both C++ and Java. There are some differences though. This post covers similarities and differences of static keyword in C++ and Java.


Like C++, static data members in Java are class members and shared among all objects. For example, in the following Java program, static variable count is used to count the number of objects created.

Example:
class Test {
    static int count = 0;
 
    Test() { 
       count++; 
    }    
    public static void main(String arr[]) {
       Test t1 = new Test();
       Test t2 = new Test();
       System.out.println("Total " + count + " objects created");        
    }
}


Output:
Total 2 objects created


3. Static member methods

Like C++, static data members and static methods can be accessed without creating an object. They can be accessed using class name. For example, in the following program, static data member count and static method fun() are accessed without any object.

Code (Java):
class Test {
    static int count = 0;
    public static void fun() { 
       System.out.println("Static fun() called"); 
    }    
}   
      
class Main
{
    public static void main(String arr[]) {
       System.out.println("Test.count = " + Test.count);        
       Test.fun();
    }
} 

So the interesting question is: when to use static member methods?
From http://stackoverflow.com/questions/2671496/java-when-to-use-static-methods



One rule-of-thumb: ask yourself "does it make sense to call this method, even if no Obj has been constructed yet?" If so, it should definitely be static.

(Btw, the converse isn't always true: you might sometimes have a method which involves two Car objects, and still want it to be static. E.g. Car theMoreEfficientOf( Car c1, Car c2 ). Although this could be converted to a non-static version, some would argue that since there isn't a "privileged" choice of which Car is more important, you shouldn't force a caller to choose one Car as the object you'll invoke the method on. This situation accounts for a fairly small fraction of all static methods, though.)


So in a class Car you might have a method double convertMpgToKpl(double mpg) which would be static, because one might want to know what 35mpg converts to, even if nobody has ever built a Car. But void setMileage(double mpg) (which sets the efficiency of one particular Car) can't be static since it's inconceivable to call the method before any Car has been constructed.


In addition, static methods have some constraints.
1) They can only call other static methods. For example, the following program fails in compilation. fun() is non-static and it is called in static main()

Code (Java):
class Main {
    public static void main(String args[]) {   
        System.out.println(fun());
    } 
    int fun() {
        return 20;
    } 
}

2) They must only access static data.
3) They cannot access this or super . For example, the following program fails in compilation.

Code (Java):
class Base {
    static int x = 0;       
}   
 
class Derived extends Base 
{
   public static void fun() {
       System.out.println(super.x); // Compiler Error: non-static variable 
                                  // cannot be referenced from a static context
   }   
}

4. Static local variables
Unlike C++, Java doesn’t support static local variables. For example, the following Java program fails in compilation.

Example (Java):
class Test {
   public static void main(String args[]) { 
     System.out.println(fun());
   } 
   static int fun()  {
     static int x= 10; //Compiler Error: Static local variables are not allowed
     return x--;
   }
} 

5. Static blocks in Java:
http://www.geeksforgeeks.org/g-fact-79/


Unlike C++, Java supports a special block, called static block (also called static clause) which can be used for static initializations of a class. This code inside static block is executed only once: the first time you make an object of that class or the first time you access a static member of that class (even if you never make an object of that class). For example, check output of following Java program.
// filename: Main.java
class Test {
    static int i;
    int j;
     
    // start of static block 
    static {
        i = 10;
        System.out.println("static block called ");
    }
    // end of static block 
}
 
class Main {
    public static void main(String args[]) {
 
        // Although we don't have an object of Test, static block is 
        // called because i is being accessed in following statement.
        System.out.println(Test.i); 
    }
}


Output:
static block called
10

Also, static blocks are executed before constructors. For example, check output of following Java program.

// filename: Main.java
class Test {
    static int i;
    int j;
    static {
        i = 10;
        System.out.println("static block called ");
    }
    Test(){
        System.out.println("Constructor called");
    }
}
 
class Main {
    public static void main(String args[]) {
 
       // Although we have two objects, static block is executed only once.
       Test t1 = new Test();
       Test t2 = new Test();
    }
}

Output:
static block called
Constructor called
Constructor called




1 comment:

  1. Static block in java

    Thanks for sharing this post, really this post is very simple and easy.

    ReplyDelete