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?
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.
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;
}
}
}
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:)
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
.
"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) {
...
}
}
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();
}
}
Sauf si vous avez des noms de variables qui se chevauchent, c'est vraiment juste pour plus de clarté lorsque vous lisez le code.
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.
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)
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;
}
- Vous savez que
foo
est une variable déclarée dans la classe externeHello
. - Vous savez que
getStringFromSomewhere()
est également une méthode déclarée dans la classe externe. - , Vous savez que
bar
appartient àWorld
classe, ets
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.
Voici les façons d'utiliser le mot-clé "this" en java:
- Utilisation du mot-clé
this
pour référencer les variables d'instance de classe en cours - Utilisation de
this()
pour appeler le constructeur de classe actuel - Utilisation du mot-clé
this
pour renvoyer l'instance de classe actuelle - Utilisation du mot-clé
this
comme paramètre de méthode
Https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
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.
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;
}
}
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.
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
}
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é.
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.