Instance variables vs static variables

  • There are 2 kinds of variables that can be defined inside a class (that is outside any method):

    public class Circle
    {
        public        double radius; // (1) an instance variable
        public static int count;     // (2) a  "static" variable
        ...
    } 

  • How are instance variables and static variables of objects different:

    • Each object has its own copy of an instance variable

    • Static variable belongs to the class and all objects of that class share the same copy of a static variable

  • In other words:

    • There is only 1 copy of a static variable in a Java program !

Experiment

Consider the following Circle class with a static variable

public class Circle
{
    public        double radius = 1;    /** An instance variable */
    public static int count;            /** A  "static" variable */

    public Circle() { }                 /** Constructor 1 for a circle object */
    
    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
    }

    public double getArea()      /** Return the area of this circle */
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(double newRadius) /** Set new radius for this circle */
    {
       radius = newRadius;
    }
}  

Let's create 2 different Circle objects and examine the difference....

Experiment

Examine the behavior when we update the instance variable radius:

public class myProg
{
    public static void main(String[] args)
    {
        Circle circle1 = new Circle(2);
        Circle circle2 = new Circle(4);

	circle1.count = 99;

	System.out.println( circle1.radius );
	System.out.println( circle1.count );  
	System.out.println( circle2.radius );
	System.out.println( circle2.count ); 
	System.out.println();

	circle1.radius++; // Updates an instance variable

	System.out.println( circle1.radius );  // Changed
	System.out.println( circle1.count );  
	System.out.println( circle2.radius );  // Unchanged --> not shared
	System.out.println( circle2.count ); 
    }
}

Reason:   instance variables are not shared !

DEMO: demo/03-classes/21-static/Demo.java + Circle.java

Experiment

Examine the behavior when we update the static variable count:

public class myProg
{
    public static void main(String[] args)
    {
        Circle circle1 = new Circle(2);
        Circle circle2 = new Circle(4);

	circle1.count = 99;

	System.out.println( circle1.radius );
	System.out.println( circle1.count );  
	System.out.println( circle2.radius );
	System.out.println( circle2.count ); 
	System.out.println();

	circle1.count++;  // Updates a static variable

	System.out.println( circle1.radius );      
	System.out.println( circle1.count );    // Changed
	System.out.println( circle2.radius );      
	System.out.println( circle2.count );    // Also changed --> shared!
    }
} 

Reason:   static variables are shared !

DEMO: demo/03-classes/21-static/Demo2.java + Circle.java

Graphical representation of instance and static variables

  • This Circle class

    public class Circle
    {
        public        double radius; // (1) an instance variable
        public static int count;     // (2) a  "static" variable
        ...
    }  

    will create Circle objects whose members are like this:

Application of static variable

  • The most common application where you need to use a static variable in a class is:

      • Writing a class that can keep a count on the number of objects that has been created by a Java program

  • How to apply a static variable to count the number of objects created:

      1. Define a static variable named count and initialize it to zero (0)

      2. Each constructor of the class must increase the count variable by one (1)

  • Why this works:

      • Because when an object is created, some constructor method is invoked once, this algorithm will keep track on the number of objects created !!

Let's write the code next...

How to keep track on the number of object created

(1) define a static variable count and initialize it to zero:

public class Circle
{
    public double radius = 1;       /** An instance variable */
    public static int count = 0;    /** A  "static" variable */

    public Circle()                 /** Constructor 1 for a circle object */
    {

    }

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;

    }

    public double getArea()      /** Return the area of this circle */
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(double newRadius) /** Set new radius for this circle */
    {
       radius = newRadius;
    }
}  

 

How to keep track on the number of object created

(2) increase the static variable count in every constructor:

public class Circle
{
    public double radius = 1;       /** An instance variable */
    public static int count = 0;    /** A  "static" variable */

    public Circle()                 /** Constructor 1 for a circle object */
    {
        count++;
    }

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;
        count++;
    }

    public double getArea()      /** Return the area of this circle */
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(double newRadius) /** Set new radius for this circle */
    {
       radius = newRadius;
    }
}  

Let's create 2 Circle objects and examine the count....

Experiment

Demo program that shows we can keep track of the number of Circle objects created:

public class myProg
{
    public static void main(String[] args)
    {
        Circle circle1 = new Circle(2);
 
	System.out.println( circle1.radius );
	System.out.println( circle1.count );  
	System.out.println();

        Circle circle2 = new Circle(4);

	System.out.println( circle2.radius );
	System.out.println( circle2.count ); 
    }
}
 

DEMO: demo/03-classes/22-static

Comment:   I define count as public to make the demo program short - otherwise, I will need accessor methods inside Circle...

Instance methods vs static methods

  • There are also 2 kinds of methods that can be defined inside a class:

    public class Circle
    {
        public int radius;           // Instance variable
    
        public double getArea()      // (1) an instance method
        {
            return 3.14159 * radius * radius;
        }
    
        public static void main( )   // (2) a  "static" method
        {
           ... // You have learned about static methods in CS170
        }
    } 

  • How are instance methods and static methods different:

    • Instance methods always has a implicit (= hidden) object reference parameter and can access instance variables

    • Static methods do not have a implicit (= hidden) object reference parameter and cannot access instance variables

Properties of static methods

  • A static method belongs to a class

    • For this reason, static methods are also known as: class methods

  • A static method can be invoked without using an object instance:

        Math.pow(x, n)

  • Static methods can only access static members:

    • Invoke other static methods

    • Access static variables

    I.e.:   static methods cannot access any instance variables nor invoke instance methods directly (i.e.: using the this variable)

When do you define a methods as a static method or as an instance method ?

  • Static methods are used to perform a task that is not associated with a particular object

  • Examples of tasks:

      • Sort an array of integers
      • Find the smallest value in an array
      • Compute the square root of a number


  • Instance methods are used to perform a task using data in a specific object

  • Examples of tasks:

      • Shuffle this deck of cards or shuffle that deck of cards
      • Compute the area of this circle (or that circle...)
      • Change the radius of this circle (or that circle...)

Invoking a static method

 

  • Static methods can be invoked in 2 different ways:

      (1) instanceVar.staticMethod( ... )
    
      (2) ClassName.staticMethod( ... )     <-- Preferred 

  • You have learned to use static methods in CS 170...

    Examples: static methods in the Math class in the Java library:

      Math.random( )
    
      Math.pow(x, 3)

Constants defined inside a class

  • Some classes may have useful constants defined in them

  • Example: Mathematical constants

      PI = 3.141592653     (π)
      E  = 2.718281828     (e)


  • Fact:

    • Because a constant can not change its value, you will only need 1 copy of it....

    Therefore:

    • A constant can always be defined as static !!

    Example:

     Math.PI     // 3.141592653589793

The static block in a class

  • A static block is a nameless and parameterless static method in a class

  • Syntax to define a static block:

    public class myClass
    {
        ...  (other memebers omitted for brevity)
    
        // A static block    
        static
        {
            ... (statements)
        }
    
    }

  • Use of a static block:

    • Static blocks are executed before the main( ) method !!

    • Static blocks are used to initialize static variables in a class

DEMO: demo/03-classes/23-static-block -- put a break inside the static block

Summary

  • Each object has its own copy of instance variables

  • All object will share 1 copy of static variables


  • Instance methods always operate on a specific instance of an object (uses the instance variables of that object)

    How to invoked an instance method:

       objectVar.instanceMethod( .... )   

  • Static methods do not operate on objects

    How to invoked a static method:

       ClassName.staticMethod( .... )  // Prefered
       objectVar.staticMethod( .... )  // Allowed, but not prefered