web-dev-qa-db-fra.com

Quand devrais-je utiliser "ceci" dans un cours?

Je sais que this fait référence à un objet actuel. Mais je ne sais pas quand j'ai vraiment besoin de l'utiliser. Par exemple, y aura-t-il une différence si j'utilise x au lieu de this.x dans certaines méthodes? Peut-être que x fera référence à une variable qui est locale pour la méthode considérée? Je veux dire variable qui est vu seulement dans cette méthode.

Qu'en est-il de this.method()? Puis-je l'utiliser? Dois-je l'utiliser. Si je viens d'utiliser method(), ne sera-t-il pas appliqué par défaut à l'objet actuel?

220
Roman

Le mot clé this est principalement utilisé dans trois situations. La première et la plus courante consiste dans les méthodes setter à désambiguïser les références aux variables. La seconde est lorsqu'il est nécessaire de passer l'instance de classe actuelle en tant qu'argument à une méthode d'un autre objet. La troisième est un moyen d'appeler des constructeurs alternatifs à partir d'un constructeur.

Cas 1: Utilisation de this pour lever les ambiguïtés sur les références aux variables. Dans les méthodes de définition Java, nous passons généralement un argument portant le même nom que la variable membre privée que nous essayons de définir. Nous assignons ensuite l'argument x à this.x. Cela indique clairement que vous attribuez la valeur du paramètre "name" à la variable d'instance "name".

public class Foo
{
    private String name;

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

Cas 2: Utilisation de this comme argument transmis à un autre objet.

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();
    }
}

Cas 3: Utilisation de this pour appeler d'autres constructeurs. Dans les commentaires, trinithis a correctement indiqué un autre usage courant de this. Lorsque vous avez plusieurs constructeurs pour une même classe, vous pouvez utiliser this(arg0, arg1, ...) pour appeler un autre constructeur de votre choix, à condition que vous le fassiez dans la première ligne de votre constructeur.

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

        //optional other lines
    }

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

J'ai également vu this utilisé pour souligner le fait qu'une variable d'instance est référencée (sans le besoin de désambiguïsation), mais c'est un cas rare à mon avis.

300
William Brendel

La deuxième utilisation importante de this (outre le fait de se cacher avec une variable locale comme beaucoup de réponses le disent déjà) consiste à accéder à une instance externe à partir d'une classe non statique imbriquée:

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;
    }
  }
}
65

Vous devez uniquement utiliser this - et la plupart des gens ne l'utilisent - que lorsqu'il existe une variable locale superposée portant le même nom. (Méthodes Setter, par exemple.)

Bien sûr, une autre bonne raison d'utiliser this est qu'elle fait apparaître intellisense dans les IDE :)

42
froadie

Le seul besoin d'utiliser le qualificatif this. est lorsqu'une autre variable de l'étendue actuelle partage le même nom et que vous souhaitez faire référence au membre de l'instance (comme décrit par William). En dehors de cela, il n'y a pas de différence de comportement entre x et this.x.

22
Adam Robinson

"this" est également utile pour appeler un constructeur depuis un autre:

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}
15
Benjamin

this est utile dans le modèle de générateur.

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();
    }

}
10
Kieren Dixon

Sauf si vous avez des noms de variables qui se chevauchent, c'est simplement pour la clarté lorsque vous lisez le code.

7
ChickenMilkBomb

Il y a beaucoup de bonnes réponses, mais il y a une autre raison très mineure de mettre this partout. Si vous avez essayé d'ouvrir vos codes source à partir d'un éditeur de texte normal (par exemple, le bloc-notes, etc.), l'utilisation de this rendra la lecture beaucoup plus claire.

Imagine ça:

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;
        }
    }
}

Cela est très clair à lire avec n'importe quel IDE moderne, mais ce sera un cauchemar total à lire avec un éditeur de texte standard.

Vous aurez du mal à savoir où réside foo, jusqu'à ce que vous utilisiez la fonction "find" de l'éditeur. Ensuite, vous crierez à getStringFromSomewhere() pour la même raison. Enfin, après que vous ayez oublié ce qu'est s, ce bar = s va vous donner le coup de grâce.

Comparez-le à ceci:

public void doSomething() {
    // More codes
    Hello.this.foo = "FOO";
    // More codes
    String s = Hello.this.getStringFromSomewhere();
    // More codes
    this.bar = s;
}
  1. Vous savez que foo est une variable déclarée dans la classe externe Hello.
  2. Vous savez que getStringFromSomewhere() est également une méthode déclarée dans la classe externe.
  3. Vous savez que bar appartient à World classe et s est une variable locale déclarée dans cette méthode.

Bien sûr, chaque fois que vous concevez quelque chose, vous créez des règles. Ainsi, lors de la conception de votre API ou de votre projet, si vos règles incluent "si une personne ouvre tous ces codes sources avec un bloc-notes, elle doit se tirer une balle dans la tête", vous ne risquez pas le faire cela .

6
Jai

@ William Brendel a fourni trois cas d'utilisation différents à la manière de Nice. 

Cas d'utilisation 1:

La page de documentation Java officielle sur this fournit les mêmes cas d'utilisation. 

Dans une méthode d'instance ou un constructeur, il s'agit d'une référence à l'objet actuel - l'objet dont la méthode ou le constructeur est appelé. Vous pouvez faire référence à n'importe quel membre de l'objet actuel depuis une méthode d'instance ou un constructeur en utilisant ceci.

Il couvre deux exemples: 

Utilisation de ceci avec un champ _ et Utilisation de ceci avec un constructeur

Cas d'utilisation 2:

Les autres cas d'utilisation qui n'ont pas été cités dans ce message: this peuvent être utilisés pour synchroniser l'objet actuel dans une application multithread afin de protéger une section critique de données et méthodes.

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

Cas d'utilisation 3:

L'implémentation de Builder pattern dépend de l'utilisation de this pour renvoyer l'objet modifié.

Se référer à ce post

Garder le constructeur dans une classe séparée (interface fluide)

3
Ravindra babu

Google a créé une page sur le site Sun qui en parle un peu.

Vous avez raison à propos de la variable; this peut en effet être utilisé pour différencier une variable de méthode d'un champ de classe .

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

Cependant, je vraiment déteste cette convention. Donner à deux variables différentes des noms littéralement identiques est une recette pour des bugs. Je préfère de loin quelque chose comme:

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

Mêmes résultats, mais sans risque de bug où vous faites accidentellement référence à x alors que vous vouliez vraiment faire référence à x à la place.

Quant à l’utiliser avec une méthode, vous avez raison sur les effets; vous obtiendrez les mêmes résultats avec ou sans. Pouvez-vous l'utiliser? Sûr. Devriez-vous l'utiliser? À vous de voir, mais étant donné que je pense personnellement que c’est une verbosité inutile qui n’ajoute aucune clarté (à moins que le code ne soit rempli de déclarations d’importation statiques), je ne suis pas disposé à l’utiliser moi-même.

2
BlairHippo

Voici les manières d’utiliser le mot-clé ‘this’ en Java:

  1. Utilisation du mot clé this pour faire référence aux variables d'instance de classe actuelles
  2. Utilisation de this() pour appeler le constructeur de la classe actuelle
  3. Utilisation du mot clé this pour renvoyer l'instance de classe actuelle
  4. Utilisation du mot clé this comme paramètre de méthode

https://docs.Oracle.com/javase/tutorial/Java/javaOO/thiskey.html

2
roottraveller

this est une référence à l'objet actuel. Il est utilisé dans le constructeur pour faire la distinction entre la variable de classe locale et la variable de classe actuelle ayant le même nom. par exemple.:

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

this peut également être utilisé pour appeler un constructeur à partir d'un autre constructeur. par exemple.: 

public class circle {
    int x;

    circle() { 
        this(1);
    }

    circle(int x) {
        this.x = x; 
    }
}
1
nouman shah

quand il y a deux variables, une variable d'instance et une autre variable locale du même nom, nous l'utilisons. faire référence à l'objet en cours d'exécution pour éviter le conflit entre les noms.

1
giri

Y aura-t-il une différence si j'utilise "x" au lieu de "this.x" dans certaines méthodes?

Généralement pas. Mais cela fait parfois une différence:

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

Si je viens d'utiliser "method ()", ne sera-t-il pas appliqué par défaut à l'objet actuel?

Oui. Mais si nécessaire, this.method() précise que l'appel est effectué par cet objet.

0
amit

this n'affecte pas le code résultant - c'est un opérateur de compilation et le code généré avec ou sans sera le même. Quand vous devez l'utiliser, cela dépend du contexte. Par exemple, vous devez l'utiliser, comme vous l'avez dit, lorsque vous avez une variable locale qui ombrage une variable de classe et que vous souhaitez faire référence à une variable de classe et non à une variable locale.

edit: par "le code résultant sera le même" je veux dire bien sûr, quand une variable dans la portée locale ne cache pas celle appartenant à la classe. Ainsi

class POJO {
   protected int i;

   public void modify() {
      i = 9;
   }

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

le code résultant des deux méthodes sera le même. La différence sera si une méthode déclare une variable locale avec le même nom

  public void m() {
      int i;
      i = 9;  // i refers to variable in method's scope
      this.i = 9; // i refers to class variable
  }
0
doc

Concernant les publications de William Brendel et dbconfessions , concernant cas 2. Voici un exemple:

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");
    }
  }

}

J'ai vu cela utilisé lors de la création d'une relation parent-enfant avec des objets. Toutefois, veuillez noter qu’il est simplifié par souci de brièveté.

0
Alija