Review:   accessing members of an object

  • An object's member can refer to:

      • A data field in the object         or      
      • A method in the object

  • After an object is created, its data can be accessed and its methods can be invoked using the dot operator (.):

     objectRefVar.dataField  references a data field in the object.
    
     objectRefVar.method(arguments)  invokes a method on the object

  • The dot (.) operator is also known as the object member access operator

  • Key point:

    • Members in an object is always accessed through a reference variable.

Where is reference variable used by the instance methods ???

Consider the instance methods in the Circle class definition again:

public class Circle
{
    public double radius = 1;       /** The radius of this circle */

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

    public Circle(double newRadius) /** Constructor 2 for a circle object */
    {
        radius = newRadius;  // Member radius not accessed with a ref. var ??
    }

    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;
    }
} 

We access the member variable radius without using any reference variable !!!   How is this possible ???

The implicit (= hidden) parameter this

Here is the dirty little secret about Java's instance methods:

  • An instance method is always invoked using an object reference variable:

     objectRefVar.method(arguments)  invokes a method on the object  

  • The variable objectRefVar is also passed to an instance method as a implicit (= hidden) parameter

    The name of the implicit (= hidden) parameter is called:

             this  

  • Let's make the hidden parameter this explicit

    (I.e.: reveal where the Java compiler uses the hidden parameter)

The implicit (= hidden) reference variable this in the instance methods

When we define a class as follows:

public class Circle
{
    public double radius = 1;       /** The radius of this circle */

    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;
    }
} 

The implicit (= hidden) reference variable this in the instance methods

The Java compiler will secretly insert the implicit parameter this in every instance method (and constructor):

public class Circle
{
    public double radius = 1;       /** The radius of this circle */             

    public Circle(Circle this) { } 

    public Circle(Circle this, double newRadius) 
    {
        radius = newRadius;
    }

    public double getArea(Circle this)     
    {
        return 3.14159 * radius * radius;
    }

    public void setRadius(Circle this, double newRadius)             
    {
       radius = newRadius;
    }
} 

The parameter this is equal to the reference variable used to access the object (E.g.: circle1.getArea())

The implicit (= hidden) reference variable this used by the instance methods

The Java compiler will also insert this. to every member access in an instance method (and constructor):

public class Circle
{
    public double radius = 1;       /** The radius of this circle */

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

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

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

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

We can add the this variable ourselves (if you wish)
DEMO: 03-classes/08-this/Circle.java      (proof that the parameter variable this exists !)

The implicit (= hidden) parameter this

Example to illustrate the passing of the implicit parameter:

  • When we invoke circle1.getArea(), the Java compiler will "secretly" pass circle1 as this to getArea():

    Therefore, the call circle1.getArea() will compute:

     circle1.radius × circle1.radius × π  =  2 × 2 × π

The implicit (= hidden) parameter this

Example to illustrate the passing of the implicit parameter:

  • And when we invoke circle2.getArea(), the Java compiler will "secretly" pass circle2 as this to getArea():

    And, the call circle2.getArea() will compute:

     circle2.radius × circle2.radius × π  =  4 × 4 × π

When is the use of this necessary ???

  • The implicit (= hidden) parameter "this" is almost never necessary to write Java classes.

  • There is only 1 case that I can think of when it is necessary to use the "this" variable (which you can easily avoid):

    • When a parameter variable has the same name as an instance variable in the class

    Example:

        /** Set new radius for this circle */
        public void setRadius(double radius)
        {
           radius = radius;  // Error: radius is ambiguous !
    
           // Fix: this.radius = radius;
        }  

    You can fix this problem with:    this.radius

DEMO: 03-classes/09-this/Circle.java

Another (rare) use of this

  • The this keyword can also be used to invoke another constructor of the same class.

    Example: instead of writing this:

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

Another (rare) use of this

  • The this keyword can also be used to invoke another constructor of the same class.

    Which is equivalent to:

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

Another (rare) use of this

  • The this keyword can also be used to invoke another constructor of the same class.

    We can also call "Circle(1)" using this(1) to set radius = 1:

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