Michal Jankowski
Michal Jankowski

Reputation: 551

Using 'this' in constructor and other methods in Java - when is it OK to skip it?

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

Answers (3)

Slava Vedenin
Slava Vedenin

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

daniu
daniu

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

Eran
Eran

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

Related Questions