"This" peut-il jamais être null en Java?

J'ai vu cette ligne dans une méthode de classe et ma première réaction a été de ridiculiser le développeur qui l'a écrit.. Mais ensuite, je me suis dit que je devrais m'assurer d'avoir raison en premier.

public void dataViewActivated(DataViewEvent e) {
    if (this != null)
        // Do some work
}

Cette ligne sera-t-elle jamais évaluée à false?

101
demandé sur Matthew Flaschen 2010-09-24 21:29:02

10 réponses

Non, il ne peut pas. si vous utilisez this, alors vous êtes dans l'instance donc this n'est pas null.

Le JLS dit:

Lorsqu'il est utilisé comme expression principale, le mot-clé indique une valeur qui est une référence à l'objet pour lequel la méthode d'instance a été invoquée (§15.12), ou à l'objet en cours de construction.

Si vous avez appelé une méthode d'un objet, l'objet existe ou vous auriez un NullPointerException avant (ou c'est une méthode statique, mais alors, vous ne pouvez pas utiliser this dedans).


Ressources :

81
répondu Colin Hebert 2010-09-25 09:25:16

C'est comme se demander " Suis-je vivant?"this ne peut jamais être null

61
répondu bragboy 2010-09-24 22:25:36

Non jamais , le mot clé 'this' lui-même représente l'instance active actuelle (objet) de cette classe dans la portée de cette classe, avec laquelle vous pouvez accéder à tous ses champs et membres (y compris les constructeurs) et les visibles de sa classe parente.

Et, plus intéressant, essayez de le définir:

this = null;

Pensez-y? Comment cela peut-il être possible, ne sera-t-il pas comme couper la branche sur laquelle vous êtes assis? Puisque le mot-clé 'this' est disponible dans la portée de la classe ainsi, dès que vous dites this = null; n'importe où dans la classe, vous demandez essentiellement à JVM de libérer la mémoire assignée à cet objet au milieu d'une opération que JVM ne peut tout simplement pas permettre car elle doit revenir en toute sécurité après avoir terminé cette opération.

De plus, la tentative de this = null; entraînera une erreur du compilateur. La raison est assez simple, un mot-clé en Java (ou dans N'importe quelle langue) ne peut jamais recevoir de valeur, c'est-à-dire qu'un mot-clé ne peut jamais être la valeur de gauche d'une affectation opération.

D'autres exemples, vous ne pouvez pas dire:

true = new Boolean(true);
true = false;
8
répondu sactiw 2015-12-04 15:20:58

Si vous compilez avec -target 1.3 ou plus tôt, alors extérieur this peut-être null. Ou au moins qu'il a utilisé pour...

7
répondu Tom Hawtin - tackline 2010-09-24 19:04:08

Non. Pour appeler une méthode d'une instance d'une classe, l'instance doit exister. L'instance est implicitement passée en paramètre à la méthode, référencée par this. Si this était null alors il n'y aurait pas eu d'instance pour appeler une méthode.

3
répondu Claudiu 2010-09-24 17:32:48

Il ne suffit pas que la langue l'applique. La machine virtuelle doit la faire respecter. À moins que la machine virtuelle ne l'applique, vous pouvez écrire un compilateur qui n'applique pas la vérification null avant d'appeler la méthode écrite en Java. Les opcodes pour une invocation de méthode d'instance incluent le chargement de cette référence sur la pile voir: http://java.sun.com/docs/books/jvms/second_edition/html/Compiling.doc.html#14787 . Remplacer ceci par une référence nulle entraînerait en effet que le test serait faux

3
répondu Rune FS 2013-02-10 07:08:11

Dans les méthodes de classe statiques, this n'est pas défini puisque this est associé à des instances et non à des classes. Je crois que cela donnerait une erreur de compilateur pour tenter d'utiliser le mot-clé this dans un contexte statique.

3
répondu burkestar 2018-02-08 07:21:39

Lorsque vous appelez une méthode sur la référence null, le NullPointerException sera lancé à partir de la machine virtuelle Java. C'est par spécification, donc si votre machine virtuelle Java est strictement conforme à la spécification, this ne serait jamais null.

1
répondu tia 2010-09-25 05:58:05

Un this normal ne peut jamais être null dans le vrai code Java1, et votre exemple utilise un this normal. Voir les autres réponses pour plus de détails.

A qualifié this devrait jamais être null, mais est possible de briser cela. Considérez ce qui suit:

public class Outer {
   public Outer() {}

   public class Inner {
       public Inner() {}

       public String toString() {
           return "outer is " + Outer.this;  // Qualified this!!
       }
   }
}

Lorsque nous voulons créer une instance de Inner, nous devons faire ceci:

public static void main(String[] args) {
    Outer outer = new Outer();
    Inner inner = outer.new Inner();
    System.out.println(inner);

    outer = null;
    inner = outer.new Inner();  // FAIL ... throws an NPE
}

La sortie est:

outer is Outer@2a139a55
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

, Montrant que notre tentative de créer un Inner avec null, en référence à son Outer a échoué.

En fait, si vous restez dans L'enveloppe" Pure Java", vous ne pouvez pas casser cela.

Cependant, chaque instance Inner a un champ synthétique final caché (appelé "this$0") qui contient la référence au Outer. Si vous êtes vraiment délicat, il est possible d'utiliser des moyens "non purs" pour assigner null au champ.

  • Vous pouvez utiliser Unsafe pour le faire.
  • Vous pouvez utiliser du code natif (par exemple JNI) pour le faire.
  • Vous pouvez le faire en utilisant réflexion.

, Soit vous le faites, le résultat final est que les Outer.this expression à évaluer null2.

En bref, il est possible qu'un this qualifié soit null. Mais c'est impossible si votre programme suit les règles "Java pur".


1 - je néglige des astuces telles que "écrire" les bytecodes à la main et les faire passer pour Du Vrai Java, peaufiner les bytecodes en utilisant BCEL ou similaire, ou sauter dans du code natif et diddling avec les registres enregistrés. OMI, qui n'est PAS Java. Hypothétiquement, de telles choses pourraient également se produire à la suite d'un bug JVM ... mais je ne me souviens pas de tous les rapports de bogues.

2 - en fait, le JLS ne dit pas quel sera le comportement, et il pourrait dépendre de l'implémentation ... entre autres choses.

1
répondu Stephen C 2017-05-11 11:27:34

Tl; dr, "this" ne peut être appelé qu'à partir d'une méthode non statique et nous savons tous qu'une méthode non statique est appelée à partir d'une sorte d'objet qui ne peut pas être null.

0
répondu Adam 2010-09-25 16:38:32