What is static and instance in Java? The difference between static variables and instance variables and between static and instance methods

As we all know the C Programming language had 4 storage classes.

  1. Auto
    The scope of auto variables was the function in which they were defined. They were destroyed when the function call ended. in every function call the variables were recreated.
  2. Extern. Essentialy global variables. Accessible to every function.
  3. Static. Static variables in functions held their values between successive function calls.
  4. and Register. register variables were stored in registers(if available). This was to speed up access and used in loops that ran many times.
We will not go very deep on this. Let us shift to Java.

Java as we all know is fully object oriented in the sense that every code is inside some class. We can declare variables directly inside the  class or inside methods. Let us define a class to begin with.


package staticandinstance;

public class ExplainingStaticAndInstance {
static String mystaticvariable="I have static data";
String myinstancedata="I have instance data";

}

We have two variables one prefixed with the static keyword and other without it. Now, I will make a function that will print the value of each one.

public void printData() {
        System.out.printf("Static data = %s\n", mystaticvariable);
        System.out.printf("Instance data = %s\n", myinstancedata);
    }

Now, we will make two objects of the class in main and call the method.


Here is the main method

    public static void main(String[] args) {
        ExplainingStaticAndInstance obj1 = new ExplainingStaticAndInstance();
        ExplainingStaticAndInstance obj2 = new ExplainingStaticAndInstance();
        obj1.printData();
        obj2.printData();
    }

Here is the output.

Static data = i have static data
Instance data = I have instance data
Static data = i have static data
Instance data = I have instance data

Here is the full code at the moment.

package staticandinstance;

public class ExplainingStaticAndInstance {

    static String mystaticvariable = "i have static data";
    String myinstancedata = "I have instance data";

    public void printData() {
        System.out.printf("Static data = %s\n", mystaticvariable);
        System.out.printf("Instance data = %s\n", myinstancedata);
    }

    public static void main(String[] args) {
        ExplainingStaticAndInstance obj1 = new ExplainingStaticAndInstance();
        ExplainingStaticAndInstance obj2 = new ExplainingStaticAndInstance();
        obj1.printData();
        obj2.printData();
    }
}

Code on Git

Now, we will change the values of the static variable and also the instance variable. Then print it once again.
Here is the changed main.

    public static void main(String[] args) {
        ExplainingStaticAndInstance obj1 = new ExplainingStaticAndInstance();
        ExplainingStaticAndInstance obj2 = new ExplainingStaticAndInstance();
        obj1.printData();
        obj2.printData();
        ExplainingStaticAndInstance.mystaticvariable = "Changed static data";
        obj1.myinstancedata = "Changed instance data in obj1";
        obj1.printData();
        obj2.printData();
    }

The output

Static data = i have static data
Instance data = I have instance data
Static data = i have static data
Instance data = I have instance data
Static data = Changed static data
Instance data = Changed instance data in obj1
Static data = Changed static data
Instance data = I have instance data

The static data has changed for both objects, while the instance only for obj1.

Having observed this we can now discuss the rationale behind static and instance.

Consider a Bank Account class with the following data to maintain. 

  1. Account No
  2. Rate of Interest
  3. Name of account holder
  4. Balance amount
Account no, balance and name will be different for each account, rate of interest will be common. If money is deposited to acc1 it will not affect the amount in other accounts.
If the rate of interest changes than it changes for everyone.
Rate of Interest is atatic and others are instance. Static variables are prefixed with the static keyword. instance do not need any keywords.

Static variables are can be accessed by using the class name and from inside any class object. In our case.
ExplainingStaticAndInstance.mystaticvariable
and from inside the method in the class.
public void printData() {
        System.out.printf("Static data = %s\n", mystaticvariable);
        System.out.printf("Instance data = %s\n", myinstancedata);
    }



Think about it in this manner. I can ask for the rate of interest applicable in a bank without mentioning an account number and also with an account number. I go to a bank office and ask them the rate of interest in savings accounts. Perfectly legitimate. I ask for the rate of interest on my account no xyz. Also legitimate.

I ask for the balance in savings accounts in a bank. The clerk would ask me the account number.


The instance variables are initialized in the constructor, how are the static variables initialized.

The answer is static block.
Here is a sample code

package staticandinstance;

public class A {

    static {
        System.out.println("Static block 1");
    }

    static {
        System.out.println("Static block 2");
    }

    public static void main(String[] args) {

    }
}

The main function is empty. We can still run this and the output is

Static block 1
Static block 2



We can have 0 to any number of static blocks and they are called in the very beginning before the class is used in any manner. Static variables should be initialized here.

What is the relation with constructors. Let us add a constructor to the class.


To call this we need to create some objects. We will create 2.


package staticandinstance;

public class A {

    static {
        System.out.println("Static block 1");
    }

    static {
        System.out.println("Static block 2");
    }

    public A() {
        System.out.println("Constructor of A");
    }

    public static void main(String[] args) {
        new A();
        new A();
    }
}


Here is the output.


Static block 1
Static block 2
Constructor of A
Constructor of A
Let us define two object blocks as well.

Object blocks are simply pairs of opening and closing curly braces and are used for keeping code that is common to all constructors.
package staticandinstance;

public class A {

    static {
        System.out.println("Static block 1");
    }

    static {
        System.out.println("Static block 2");
    }

    {
        System.out.println("Object block 1");
    }

    {
        System.out.println("Object block 2");
    }

    public A() {
        System.out.println("Zero parameter constructor of A");
    }

    public A(Object a) {
        System.out.println("One parameter constructor of A");
    }

    public static void main(String[] args) {
        new A();
        new A(0);
    }
}


Static block 1
Static block 2
Object block 1
Object block 2
Zero parameter constructor of A
Object block 1
Object block 2
One parameter constructor of A

The Object blocks are instance while the static blocks are not. The easiest way to check this is by accessing the this variable.

It will be accessible in object blocks and not in static blocks.

package staticandinstance;

public class A {

    static {
        System.out.println("Static block 1");
//        System.out.println("This = " + this); // This is not allowed
    }

    static {
        System.out.println("Static block 2");

    }

    {
        System.out.println("Object block 1");
        System.out.println("This = " + this);
    }

    {
        System.out.println("Object block 2");
    }

    public A() {
        System.out.println("Zero parameter constructor of A");
    }

    public A(Object a) {
        System.out.println("One parameter constructor of A");
    }

    @Override
    public String toString() {
        return "Class A";
    }

    public static void main(String[] args) {
        new A();
        new A(0);
    }
}

Output

Static block 1
Static block 2
Object block 1
This = Class A
Object block 2
Zero parameter constructor of A
Object block 1
This = Class A
Object block 2
One parameter constructor of A

How do static and instance blocks behave during inheritance. Let us create a new class B that extends A.

package staticandinstance;

public class B extends A {

    static {
        System.out.println("Static block 1 in B");
//        System.out.println("This = " + this); // This is not allowed
    }

    static {
        System.out.println("Static block 2 in B");

    }

    {
        System.out.println("Object block 1 in B");
        System.out.println("This = " + this);
    }

    {
        System.out.println("Object block 2 in B");
    }

    public B() {
        System.out.println("Zero parameter constructor of B");
    }

    public B(Object a) {
        System.out.println("One parameter constructor of B");
    }

    @Override
    public String toString() {
        return "Class B";
    }
    public static void main(String[] args) {
       
    }
}


Output 

Static block 1 in A
Static block 2 in A
Static block 1 in B
Static block 2 in B

The static block of the super class is called first. This will be extended if the inheritance chain was longer.


What happens if we create objects?
Code

package staticandinstance;

public class A {

    static {
        System.out.println("Static block 1 in A");
//        System.out.println("This = " + this); // This is not allowed
    }

    static {
        System.out.println("Static block 2 in A");

    }

    {
        System.out.println("Object block 1 in A");
        System.out.println("This = " + this);
    }

    {
        System.out.println("Object block 2 in A");
    }

    public A() {
        System.out.println("Zero parameter constructor of A");
    }

    public A(Object a) {
        System.out.println("One parameter constructor of A");
    }

    @Override
    public String toString() {
        return "Class A";
    }

    public static void main(String[] args) {
        new A();
        new A(0);
    }
}


Output


Static block 1 in A
Static block 2 in A
Static block 1 in B
Static block 2 in B
Object block 1 in A
This = Class B
Object block 2 in A
Zero parameter constructor of A
Object block 1 in B
This = Class B
Object block 2 in B
Zero parameter constructor of B
Object block 1 in A
This = Class B
Object block 2 in A
Zero parameter constructor of A
Object block 1 in B
This = Class B
Object block 2 in B
Zero parameter constructor of B

Contact us for software training, education or development










 

Post a Comment

0 Comments