Reputation: 551
I'm new to Java, so forgive me if it's a stupid question. I tried to find a clear answer on this forum but with no joy.
I know what 'this' is. It know it refers to an actual instance and helps narrow the context when targeting a variable, but I found that it is possible to execute the code without any issues despite not using 'this' phrase. Turns out it depends on how you name your parameters when you declare methods. As you can see below, code returns 'null' if my parameter is named the same as the state I'm initialising/modifying.
This works only in the class where the variables are declared. You'd still have to use 'this' in any sub-class, if it tried to access/modify a variable declared in its parent class.
Now, would this be considered incorrect and should it be avoided even though it seems to be working fine?
Thanks!
class Student {
protected String name;
protected int age;
protected String course;
public Student(String passName, int passAge, String course) {
name = passName;
age = passAge;
course = course; // here my parameter is named the same as the state and it will return 'null' unless we use 'this'
}
public void update(String newName, int newAge, String newCourse) {
name = newName;
age = newAge;
course = newCourse; // here I set the name of my parameter to be different and it works
}
public void display() {
System.out.println("Name: " + name + "\n Age: " + age + "\n Course: " + course + "\n");
}
public static void main(String[] args) {
Student s1 = new Student("John", 20, "Java 101");
s1.display();
s1.update("Johnny", 21, "Java 101");
s1.display();
}
}
Output:
Name: John
Age: 20
Course: null
Name: Johnny
Age: 21
Course: Java 101
Upvotes: 2
Views: 2351
Reputation: 60094
I think you should read official documantation about "this" keyword.
Using this with a Field The most common reason for using the this keyword is because a field is shadowed by a method or constructor parameter.
For example, the Point class was written like this
public class Point { public int x = 0; public int y = 0; //constructor public Point(int a, int b) { x = a; y = b; } }
but it could have been written like this:
public class Point { public int x = 0; public int y = 0; //constructor public Point(int x, int y) { this.x = x; this.y = y; } }
Each argument to the constructor shadows one of the object's fields — inside the constructor x is a local copy of the constructor's first argument. To refer to the Point field x, the constructor must use this.x.
About you question:
Now, would this be considered incorrect and should it be avoided even though it seems to be working fine?
It is depends for code style do yoy have in your projects or teams. Technically, both ways are possible and correct, using name = newName
is shorter, and using this.name = name
is more safe to avoid mistakes.
Upvotes: 2
Reputation: 14999
It's the variable name that counts. Java always uses the variable in the closest scope available, so if you use a parameter with the same name, it will use the parameter. To avoid that, you need to qualify the field with this
.
Here (irrelevant code removed):
public Student(String course) {
course = course;
}
you assign the value of course
to the parameter course
, so the field course
remains unchanged. For instance, if you do this:
public Student(final String course) {
course = course;
}
it will not compile because the final
keyword means you're not allowed to assign a new value to the variable (in this case, parameter course
).
So you need to use this
to assign to the field.
public Student(final String course) {
this.course = course;
}
It's never "incorrect" to use this
, but you might consider it good practice to not name parameters the same as fields anyway (and there are warnings to activate in IDEs if you do, to prevent exactly that).
Upvotes: 0
Reputation: 393781
As you noticed, if you give an instance variable the same name as a constructor argument, the assignment such as
course = course;
doesn't initialize the instance variable, since the constructor's argument course
, which is a local variable, hides the instance variable of the same name. You are assigning the local variable to itself.
Hence the instance variable remains null
.
You'll have to write
this.course = course;
in order for the assignment to work.
If, on the other hand, the name of the instance variable is different from the constructor argument's name, you can assign the constructor's argument to the instance variable without using the this
prefix.
both
course = newCourse;
and
this.course = newCourse;
would work fine.
Note that using the this
prefix even when it's not mandatory has an advantage of spotting bugs.
For example, if you wrote by mistake
newCourse = course;
the compiler will not complain, but your course
instance variable won't be initialized.
On the other hand, if you wrote by mistake
this.newCourse = course;
the compiler will give a compilation error, since newCourse
is not an instance variable.
Upvotes: 3