Quand devrais-je utiliser "ceci" dans une classe?


Je sais que this fait référence à un objet courant. 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 des méthodes? Peut être x fera référence à une variable locale pour la méthode considérée? Je veux dire variable qui n'est vue que dans cette méthode.

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

Author: Gabriel Ščerbák, 2010-03-09

17 answers

Le mot-clé this est principalement utilisé dans trois situations. La première et la plus courante est dans les méthodes setter pour désambiguiser les références de 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. Le troisième est un moyen d'appeler des constructeurs alternatifs à partir d'un constructeur.

Cas 1: Utilisation de this pour désambiguiser les références de variables. Dans les méthodes Java setter, nous passons généralement un argument avec le même nom en tant que variable membre privée que nous tentons de définir. Nous affectons 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: Utilisant this comme argument passé à 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: En utilisant this pour appeler des constructeurs alternatifs. Dans les commentaires, trinithis correctement souligné une autre utilisation courante de this. Lorsque vous avez plusieurs constructeurs pour une seule classe, vous pouvez utiliser this(arg0, arg1, ...) pour appeler un autre constructeur de votre choix, si vous le faites 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 besoin de désambiguïsation), mais c'est un cas rare à mon avis.

 278
Author: William Brendel, 2017-06-01 18:51:13

La deuxième utilisation importante de this (en plus de se cacher avec une variable locale comme beaucoup de réponses le disent déjà) est lors de l'accès à 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;
    }
  }
}
 61
Author: Christopher Oezbek, 2010-03-09 18:50:55

Vous n'avez besoin d'utiliser this - et la plupart des gens ne l'utilisent que lorsqu'il y a une variable locale qui se chevauche avec le même nom. (Méthodes Setter, par exemple.)

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

 39
Author: froadie, 2010-03-09 18:02:30

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

 20
Author: Adam Robinson, 2010-03-09 18:01:04

"ce" est également utile lors de l'appel d'un constructeur à partir d'un autre:

public class MyClass {
    public MyClass(String foo) {
        this(foo, null);
    }
    public MyClass(String foo, String bar) {
        ...
    }
}
 15
Author: Benjamin, 2010-03-09 20:14:45

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

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
Author: Kieren Dixon, 2017-11-18 13:00:29

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

 6
Author: ChickenMilkBomb, 2010-03-09 18:00:52

Google a tourné une page sur le site Sun qui discute un peu de cela.

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. {[0]}

Cependant, je déteste vraiment cette convention. Donner à deux variables différentes des noms littéralement identiques est une recette pour les bugs. Je préfère quelque chose le long des lignes de: {[1]}

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

, Comme à l'utiliser avec une méthode, vous avez raison sur les effets; vous obtiendrez les mêmes résultats avec ou sans elle. Pouvez-vous l'utiliser? Assurer. Devriez-vous utiliser? À vous de décider, 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 d'instructions d'importation statiques), je ne suis pas enclin à l'utiliser moi-même.

 3
Author: BlairHippo, 2010-03-09 18:11:21

La réponse de @ William Brendel a fourni trois cas d'utilisation différents de manière agréable.

cas d'Utilisation 1:

Page de documentation java officielle surce 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 courant - l'objet dont la méthode ou le constructeur est appelé. Vous pouvez faire référence à n'importe quel membre de l'objet courant à partir d'une instance d'une méthode ou d'un constructeur en utilisant ce.

, Il couvre deux exemples :

l'Utilisation de ce avec un Champ et à l'Aide de ce avec un Constructeur

cas d'Utilisation 2:

Autre cas d'utilisation qui n'a pas été cité dans cet article: this peut être utilisé pour synchroniser l'objet actuel dans une application multi-thread pour protéger la section critique des données et des méthodes.

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

cas d'Utilisation 3:

L'implémentation du modèleBuilder dépend de l'utilisation de this pour retourner l'objet modifié.

Reportez-vous à ce post

Garder le constructeur dans une classe distincte (interface fluide)

 3
Author: Ravindra babu, 2017-09-25 18:31:25

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, bloc-notes, etc.), l'utilisation de this le rendra beaucoup plus clair à lire.

Imaginez ceci:

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

C'est très clair à lire avec n'importe quelE moderne, mais ce sera un cauchemar total à lire avec un éditeur de texte ordinaire.

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

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 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 quelqu'un ouvre tous ces codes source avec un bloc-notes, il devrait se tirer une balle dans la tête", alors vous êtes tout à fait bien de ne pas faire ce.

 3
Author: Jai, 2018-02-22 01:42:26

Voici les façons d'utiliser le mot-clé "this" en java:

  1. Utilisation du mot-clé this pour référencer les variables d'instance de classe en cours
  2. Utilisation de this() pour appeler le constructeur de classe actuel
  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
Author: roottraveller, 2016-10-10 12:39:08

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

 1
Author: giri, 2010-03-09 19:50:27

this est une référence à l'objet courant. Il est utilisé dans le constructeur pour faire la distinction entre la variable de classe locale et la variable de classe actuelle qui ont 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 utiliser 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
Author: nouman shah, 2015-06-28 14:13:21

Y aura une différence si j'utilise "x" au lieu de "this.x " dans certaines des 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 j'utilise simplement "method()", ne sera-t-il pas, par défaut, appliqué à l'objet actuel?

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

 0
Author: amit_grepclub, 2010-03-09 18:01:48

this n'affecte pas le code résultant - c'est l'opérateur de temps de compilation et le code généré avec ou sans lui sera le même. Quand vous devez l'utiliser, dépend du contexte. Par exemple, vous devez l'utiliser, comme vous l'avez dit, lorsque vous avez une variable locale qui ombre la variable de classe et que vous voulez faire référence à la 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
Author: doc, 2010-03-09 18:27:22

En ce qui concerne les messages de William Brendelet la question de dbconfessions, en ce qui concerne 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 construction de relations parent-enfant avec des objets. Cependant, veuillez noter qu'il est simplifié par souci de brièveté.

 0
Author: Alija, 2017-12-05 19:41:39

Pour s'assurer que les membres de l'objet courant sont utilisés. Dans les cas où la sécurité des threads est un problème, certaines applications peuvent modifier les valeurs de membre d'objets incorrectes, pour cette raison, cela doit être appliqué au membre afin que la valeur de membre d'objet correcte soit utilisée.

Si votre objet n'est pas concerné par la sécurité des threads, il n'y a aucune raison de spécifier quelle valeur de membre d'objet est utilisée.

 -7
Author: Myster October, 2010-03-09 20:40:51