When should I use "this" in a class?
Asked Answered
B

17

367

I know that this refers to a current object. But I do not know when I really need to use it. For example, will be there any difference if I use x instead of this.x in some of the methods? May be x will refer to a variable which is local for the considered method? I mean variable which is seen only in this method.

What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?

Butanone answered 9/3, 2010 at 17:57 Comment(0)
M
469

The this keyword is primarily used in three situations. The first and most common is in setter methods to disambiguate variable references. The second is when there is a need to pass the current class instance as an argument to a method of another object. The third is as a way to call alternate constructors from within a constructor.

Case 1: Using this to disambiguate variable references. In Java setter methods, we commonly pass in an argument with the same name as the private member variable we are attempting to set. We then assign the argument x to this.x. This makes it clear that you are assigning the value of the parameter "name" to the instance variable "name".

public class Foo
{
    private String name;

    public void setName(String name) {
        this.name = name;
    }
}

Case 2: Using this as an argument passed to another object.

public class Foo
{
    public String useBarMethod() {
        Bar theBar = new Bar();
        return theBar.barMethod(this);
    }

    public String getName() {
        return "Foo";
    }
}

public class Bar
{
    public void barMethod(Foo obj) {
        obj.getName();
    }
}

Case 3: Using this to call alternate constructors. In the comments, trinithis correctly pointed out another common use of this. When you have multiple constructors for a single class, you can use this(arg0, arg1, ...) to call another constructor of your choosing, provided you do so in the first line of your constructor.

class Foo
{
    public Foo() {
        this("Some default value for bar");

        //optional other lines
    }

    public Foo(String bar) {
        // Do something with bar
    }
}

I have also seen this used to emphasize the fact that an instance variable is being referenced (sans the need for disambiguation), but that is a rare case in my opinion.

Moersch answered 9/3, 2010 at 17:59 Comment(15)
+1 For mentioning that you can also pass this as an argument. this is not only used for scope disambiguation.Guadalcanal
Of course there is also this(arg1, arg2, ...) inside a constructor.Compete
Just wondering if adding others answers onto your own is common practice on SO? It seems to happen often enough.Gerge
@Hazior: I tend to write a short answer and then add to it over time. Sometimes that overlaps with other people's answers, sometimes not. In the case of my latest edit, trinithis pointed out another common use of this that I forgot, so I added it to my answer. I don't see anything wrong with this because the end result is a better answer overall, which is precisely the purpose of SO. I also try to give credit wherever possible, as I did in the case of trinithis.Moersch
You have examples for case 1 and 3. Can you please give an example of case 2 where the current class instance is used as an argument for a method of another class?Templet
is it best practice to use this. even when there is no conflict?Ld
@AStar In most of the Java codebases I've worked with over the years, this is only used if disambiguation is truly necessary, like in my setter example above. Coding styles and "best practices" can vary widely depending on who you ask, of course, but in general, I recommend choosing reasonable patterns and sticking to them. Consistency, even just internally within a single codebase, goes a long way towards readability and maintainability.Moersch
@ThomasEding why not we use Constructor(arg1,arg2....) instead this(arg1,arg2..)Legendary
But what I don't understand is why you couldn't just use public void setName(String nameIn) { name = nameIn; } it totally works and the this is kind of implied.Monafo
TIL that you can also use "this" when you need to access local variables of the enclosing scope.Hord
@PixMach, That is bad because it's hungarian notation. I go a step further and just use 'item' rather than 'name'. Writing setName(name) is redundant because you are writing 'name' twice. The parameter is implied by the method name already.Debroahdebs
This only obliquely answers the last paragraph of the question: "What about this.method()? Can I use it? Should I use it. If I just use method(), will it not be, by default, applied to the current object?" It would be great if it answered it head-on.Vannie
Thank you for the answer. Java's "this" was very confusing for me after Objective-C "self" which also called getters. Now I understand the concept better!Digiacomo
I know the Case 3 code is a code snippet, but we can't really have 2 public classes within the same .java file, right?Feeze
i new in java, in case no2, error in my computer, i can not figure out why, can you give the correct code ?Signboard
P
81

The second important use of this (beside hiding with a local variable as many answers already say) is when accessing an outer instance from a nested non-static class:

public class Outer {
  protected int a;

  public class Inner {
    protected int a;

    public int foo(){
      return Outer.this.a;
    }

    public Outer getOuter(){
      return Outer.this;
    }
  }
}
Phobos answered 9/3, 2010 at 18:50 Comment(0)
V
51

You only need to use this - and most people only use it - when there's an overlapping local variable with the same name. (Setter methods, for example.)

Of course, another good reason to use this is that it causes intellisense to pop up in IDEs :)

Viridian answered 9/3, 2010 at 18:2 Comment(1)
But then you have to backspace it after you look it up. Programming is tiring!Debroahdebs
Z
32

The only need to use the this. qualifier is when another variable within the current scope shares the same name and you want to refer to the instance member (like William describes). Apart from that, there's no difference in behavior between x and this.x.

Zoroaster answered 9/3, 2010 at 18:1 Comment(12)
And if you have duplicate names, one of your variables should be renamed as it's almost definitely named improperly. Or at the very least, could be named better.Symphonic
@Chad: It's common practice in Java setter methods. However, outside of setter methods, your statements generally holds.Moersch
You may want to use this.x to make your code read a little bit more clearly also, the maintainability/readability of code is also a factor that you should be considering...Blacktop
@Chad: I cannot agree enthusiastically enough. Good Lord, just because "this." allows you to give two different variables the same name, why would you WANT to?Xuthus
@Blair: Reading your answer makes it clear that you don't prefer this practice in setter methods, but many people do (I'd include myself in that list). If I have a setter method that takes a value, clearly the value passed in is to be the "new" value, so adding "new" to the variable name seems to add needless redundancy to the public API.Zoroaster
I posted an answer that uses it in a little more unique format . . . I think. I refer to the whole object itself to add it to a list for later access.Gerge
@Adam: I hear you. I know it's common practice, but I personally chalk this up to "If all the other developers are jumping off a cliff...." If your setter is doing anything interesting and not just a one-liner, I really do think you're asking for trouble if you give two different variables identical names. Just one code monkey's opinion, of course.Xuthus
good answer. not need to long big answers. apart conventions (like setters) the only must place to use (this.) is when there are more than one variable with the same name in same scope.Bugs
"this" does not allow for two var names to be the same. It allows for args to have the same name as a var in the class a method is created; which is very useful IMO. I like clean, easy to read code. I don't like to have to think if I am looking at a param or a class var. Not to mention, using "this." brings up all the class nonstatic methods and fields for easy reference in most compilers.Shennashensi
@nixxbb: Sure it does; an instance member is no less a "var" than a local variable or a parameter. As I said in the answer, the only need to use this is when you are dealing with an instance or static variable (or field, if you prefer) that has the same name as a local variable (i.e. declared or a parameter).Zoroaster
@AdamRobinson, being on stack, dealing with all the nitpickers, I should have clarified my reply to say - " "this" does not allow two class fileds to have the same name". - Which seemed to be getting lost in the details. Most people can understand what I meant from reading my whole comment and not just jumping to conclusions from reading the first 5 words. You are using the term "instance member", and that makes your point valid, but since "this" is such a beginner topic, I thought there needed to be some clarification there even if it warranted a reply restating the obvious.Shennashensi
nix, obviously you could never have 2 members with the same name. That is why your initial comment is redundant and way too nitpicky. Think about the fact you can create a variable within a method that is the same name as a class variable.Debroahdebs
D
15

"this" is also useful when calling one constructor from another:

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}
Dineen answered 9/3, 2010 at 20:14 Comment(0)
D
15

There are a lot of good answers, but there is another very minor reason to put this everywhere. If you have tried opening your source codes from a normal text editor (e.g. notepad etc), using this will make it a whole lot clearer to read.

Imagine this:

public class Hello {
    private String foo;

    // Some 10k lines of codes

    private String getStringFromSomewhere() {
        // ....
    }

    // More codes

    public class World {
        private String bar;

        // Another 10k lines of codes

        public void doSomething() {
            // More codes
            foo = "FOO";
            // More codes
            String s = getStringFromSomewhere();
            // More codes
            bar = s;
        }
    }
}

This is very clear to read with any modern IDE, but this will be a total nightmare to read with a regular text editor.

You will struggle to find out where foo resides, until you use the editor's "find" function. Then you will scream at getStringFromSomewhere() for the same reason. Lastly, after you have forgotten what s is, that bar = s is going to give you the final blow.

Compare it to this:

public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}
  1. You know foo is a variable declared in outer class Hello.
  2. You know getStringFromSomewhere() is a method declared in outer class as well.
  3. You know that bar belongs to World class, and s is a local variable declared in that method.

Of course, whenever you design something, you create rules. So while designing your API or project, if your rules include "if someone opens all these source codes with a notepad, he or she should shoot him/herself in the head," then you are totally fine not to do this.

Dehart answered 22/2, 2018 at 1:42 Comment(3)
great answer @DehartChromonema
The first reason to shoot would be writing classes with several 10k lines of code especially if the code is already splitted to different classes which don't need to be nested :)Umbrian
@Umbrian Lol true xDDehart
P
13

this is useful in the builder pattern.

public class User {

    private String firstName;
    private String surname;

    public User(Builder builder){
        firstName = builder.firstName;
        surname = builder.surname;
    }

    public String getFirstName(){
        return firstName;
    }

    public String getSurname(){
        return surname;
    }

    public static class Builder {
        private String firstName;
        private String surname;

        public Builder setFirstName(String firstName) {
            this.firstName = firstName;
            return this;
        }

        public Builder setSurname(String surname) {
            this.surname = surname;
            return this;
        }

        public User build(){
            return new User(this);
        }

    }

    public static void main(String[] args) {
        User.Builder builder = new User.Builder();
        User user = builder.setFirstName("John").setSurname("Doe").build();
    }

}
Pula answered 28/7, 2011 at 12:16 Comment(2)
This was the type of answer I wanted when I searched and ended up here, but you have no explanation of your code, so most people who are asking about "this", won't understand what "return new user(this);" means, as I don't...Shennashensi
The Builder pattern is used to specify parameters clearly on construction. Instead of having new User(string, string) with no easy way to tell which string was which, you'd have new Builder().setFirstName("Jane").setSurname("Smith").build(). You return this from the Builder.set...() functions so you can chain them.Unmanly
W
8

Unless you have overlapping variable names, its really just for clarity when you're reading the code.

Whereon answered 9/3, 2010 at 18:0 Comment(3)
When you see constantly the this keyword when it's not necessary it's just boilerplate code making the code harder to read.Heartthrob
I just came across an open source project that is demanding all members be prefixed with 'this'. Apart from that the project is very well written but i'm tempted to get into religious debate with them.Debroahdebs
@Heartthrob I know this is really old but... this does NOT make the code harder to read lmao.Hypnogenesis
P
4

@William Brendel answer provided three different use cases in nice way.

Use case 1:

Offical java documentation page on this provides same use-cases.

Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.

It covers two examples :

Using this with a Field and Using this with a Constructor

Use case 2:

Other use case which has not been quoted in this post: this can be used to synchronize the current object in a multi-threaded application to guard critical section of data & methods.

synchronized(this){
    // Do some thing. 
}

Use case 3:

Implementation of Builder pattern depends on use of this to return the modified object.

Refer to this post

Keeping builder in separate class (fluent interface)

Plumlee answered 17/9, 2016 at 16:44 Comment(0)
X
2

Google turned up a page on the Sun site that discusses this a bit.

You're right about the variable; this can indeed be used to differentiate a method variable from a class field.

    private int x;
    public void setX(int x) {
        this.x=x;
    }

However, I really hate that convention. Giving two different variables literally identical names is a recipe for bugs. I much prefer something along the lines of:

    private int x;
    public void setX(int newX) {
        x=newX;
    }

Same results, but with no chance of a bug where you accidentally refer to x when you really meant to be referring to x instead.

As to using it with a method, you're right about the effects; you'll get the same results with or without it. Can you use it? Sure. Should you use it? Up to you, but given that I personally think it's pointless verbosity that doesn't add any clarity (unless the code is crammed full of static import statements), I'm not inclined to use it myself.

Xuthus answered 9/3, 2010 at 18:5 Comment(5)
It's not a convention, it's a program language scoping mechanism. What you listed--using newX (I prefer pX for parameter x) is a convention.Araroba
@Bill K: I don't understand the distinction you're making. I can choose to name the input variable x, or newX, or pX, or mangroveThroatWarblerX. How is choosing to give it a name identical to the variable it's setting NOT a convention, while prepending "new" or "p" or "Gratuitous Monty Python References" ARE conventions?Xuthus
"Gratuitoud Monty Python References" is not a convention, it's the LAW.Zoroaster
+1: We use a different naming standard for arguments and method variables than that for class variables for this reason. We abbreviate arguments/method vars and use full words for class/instance variables.Pinter
Solving it by using a naming convention is, hmm, a convention. Solving it by using a language feature--I guess choosing to never use that language feature or always use it would be a convention... Using this. for every time you access a member would be a convention. Guess it doesn't matter much, I hate .this as well.Araroba
C
2

Following are the ways to use ‘this’ keyword in java :

  1. Using this keyword to refer current class instance variables
  2. Using this() to invoke current class constructor
  3. Using this keyword to return the current class instance
  4. Using this keyword as method parameter

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

Content answered 10/10, 2016 at 12:39 Comment(0)
V
1

when there are two variables one instance variable and other local variable of the same name then we use this. to refer current executing object to avoid the conflict between the names.

Valtin answered 9/3, 2010 at 19:50 Comment(0)
F
1

this is a reference to the current object. It is used in the constructor to distinguish between the local and the current class variable which have the same name. e.g.:

public class circle {
    int x;
    circle(int x){
        this.x =x;
        //class variable =local variable 
    }
} 

this can also be use to call one constructor from another constructor. e.g.:

public class circle {
    int x;

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}
Fight answered 28/6, 2015 at 13:37 Comment(0)
A
0

Will be there any difference if I use "x" instead of "this.x" in some of the methods?

Usually not. But it makes a difference sometimes:

  class A {
     private int i;
     public A(int i) {
        this.i = i; // this.i can be used to disambiguate the i being referred to
     }
  }

If I just use "method()", will it not be, by default, applied to the current object?

Yes. But if needed, this.method() clarifies that the call is made by this object.

Abaxial answered 9/3, 2010 at 18:1 Comment(0)
D
0

this does not affect resulting code - it is compilation time operator and the code generated with or without it will be the same. When you have to use it, depends on context. For example you have to use it, as you said, when you have local variable that shadows class variable and you want refer to class variable and not local one.

edit: by "resulting code will be the same" I mean of course, when some variable in local scope doesn't hide the one belonging to class. Thus

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

   public void thisModify() {
      this.i = 9;
   }
}

resulting code of both methods will be the same. The difference will be if some method declares local variable with the same name

  public void m() {
      int i;
      i = 9;  // i refers to variable in method's scope
      this.i = 9; // i refers to class variable
  }
Dogmatist answered 9/3, 2010 at 18:5 Comment(0)
P
0

With respect to William Brendel's posts and dbconfessions question, regarding case 2. Here is an example:

public class Window {

  private Window parent;

  public Window (Window parent) {
    this.parent = parent;
  }

  public void addSubWindow() {
    Window child = new Window(this);
    list.add(child);
  }

  public void printInfo() {
    if (parent == null) {
      System.out.println("root");
    } else {
      System.out.println("child");
    }
  }

}

I've seen this used, when building parent-child relation's with objects. However, please note that it is simplified for the sake of brevity.

Palinode answered 5/12, 2017 at 19:41 Comment(0)
M
-10

To make sure that the current object's members are used. Cases where thread safety is a concern, some applications may change the wrong objects member values, for that reason this should be applied to the member so that the correct object member value is used.

If your object is not concerned with thread safety then there is no reason to specify which object member's value is used.

Mariomariology answered 9/3, 2010 at 20:40 Comment(2)
This really isn't the case. I'm not even sure what case you're thinking of, but an example might be helpful to understand what you're trying to say.Calamus
Yes. I know what you are explaining involves thread safety. There is no correct answer to this question that involves thread safety. If "this" is necessary to refer to the correct object, then once it does so, the method or attribute will be thread safe if and only if it is synchronized. If the reference is at all ambiguous, it will be ambiguous whether or not multi-threading is an issue.Calamus

© 2022 - 2024 — McMap. All rights reserved.