Reputation:
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
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
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
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
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