user9753255
user9753255

Reputation:

Why is the "this" keyword used in Constructor and Setters?

A constructor is used to initialize a value and assign it to the class variable in the time of creating the class instance, right?

public class Joke{
   private String jokeSetup;
   private String jokePunchLine;

   public Joke(String jokeSetup , String jokePunchLine){
       this.jokeSetup=jokeSetup;
       this.jokePunchLine=jokePunchLine;
   }
}  

Consider the following:

public Joke(String jokeSetup , String jokePunchLine) 

Is another variable with same name created?

If so, why are they assigned to the former jokeSetup and jokePunchLine values?

PS:This code is not created by me.It was shown in the videos from which I am learning Java.

Upvotes: 3

Views: 625

Answers (4)

T.J. Crowder
T.J. Crowder

Reputation: 1074949

The purpose of a constructor is to initialize the object that was just created, for instance by filling in its instance fields (also called instance variables). this is used in your constructor to refer to the instance the constructor is initializing.

In your example constructor, you have parameters and instance fields. The constructor is taking the values of the parameters and assigning those values to the instance fields:

public Joke(String jokeSetup , String jokePunchLine)
//          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- Declares parameters this
//                                                      constructor accepts when
//                                                      called
{
//                 vvvvvvvvv------------ parameter
    this.jokeSetup=jokeSetup;
//  ^^^^^^^^^^^^^^---------------------- instance field

//                     vvvvvvvvvvvvv---- parameter
    this.jokePunchLine=jokePunchLine;
//  ^^^^^^^^^^^^^^^^^^------------------ instance field
}

The constructor could initialize instance fields with constant values instead, or by using a parameter value indirectly (for instance, looking something up), etc. It's not always a direct one-to-one assignment as it is in your example.

In your example, the parameters have the same names as the instance fields, but that's not a requirement. For instance, this constructor does exactly the same thing as yours:

public Joke(String theJokeSetup , String theJokePunchLine)
//                 ^---------------------^---------- Note the name changes
{
//                   vvvvvvvvvvvv------------ parameter
    this.jokeSetup = theJokeSetup;
//  ^^^^^^^^^^^^^^--------------------------- instance field

//                       vvvvvvvvvvvvvvvv---- parameter
    this.jokePunchLine = theJokePunchLine;
//  ^^^^^^^^^^^^^^^^^^----------------------- instance field
}

Java lets you leave off the this. part when referring to an instance field and just use the field name on its own (e.g. jokeSetup instead of this.jokeSetup). You can't do that in your constructor unless you rename the parameters, though, because they have the same names as the instance fields, so jokeSetup in your constructor is the parameter, not the field. When there's a conflict like that, the most local identifier takes precedence (in your constructor, the parameter is the most local).

When there's no conflict, it's a matter of style whether you use the this. part or not. (I always use this., I find it clearer.) So for instance, here's another version of that constructor which does exactly the same thing as your original:

public Joke(String theJokeSetup , String theJokePunchLine)
//                 ^---------------------^---------- Note the name changes
{
//              vvvvvvvvvvvv------------ parameter
    jokeSetup = theJokeSetup;
//  ^^^^^^^^^--------------------------- instance field

//                  vvvvvvvvvvvvvvvv---- parameter
    jokePunchLine = theJokePunchLine;
//  ^^^^^^^^^^^^^----------------------- instance field
}

I mention this because, again, when there's no conflict, it's a matter of style, and you'll see this style used sometimes.

Upvotes: 7

Madhusudan Sharma
Madhusudan Sharma

Reputation: 60

A parametrized constructor can be used to initialize value to the variables in the time of creating it. When the parameters and variable names are same then in this case to differentiate between both, we use this keyword. This keyworord always refer to local variable of the method or class.

Upvotes: 2

Phil
Phil

Reputation: 164891

Java has an implied context for symbol names; the class instance (ie this) for non-static contexts and the class (eg Joke) for static.

This lets you omit the context when there is no conflict for the symbol name. For example

public String getJokeSetup() {
    return jokeSetup; // no "this." required, it's implied
}

When there is a conflict for the name such as the case with a method argument named the same as a field, you need to explicitly define the context, eg

public void setJokeSetup(final String jokeSetup) {
    // you must prefix the field with "this." to differentiate it from the argument
    this.jokeSetup = jokeSetup; 
}

Finally, here's an example that avoids a symbol name conflict

public void setJokeSetup(final String js) {
    jokeSetup = js;
}

It is fairly typical to name arguments the same as the fields they correspond to but you're certainly not constricted to such a convention.

Upvotes: 1

GhostCat
GhostCat

Reputation: 140525

The class has a field named jokeSetup. The method has a parameter of the same name that shadows that field.

So in essence there are two variables with the same name.

Using this makes it possible to again differentiate the two different usages of the same name, as this.whatever always denotes the corresponding field.

And you nailed it: shadowing is actually not a good idea. But this "pattern" is actually very common in Java. You could avoid it by giving the parameter a different name, such as _jokeSetup, but deviating from common practices is also bad practice.

Upvotes: 2

Related Questions