variable - Est-ce que "this" peut être nul en Java?




variable this java (7)

Vu cette ligne dans une méthode de classe et ma première réaction était de ridiculiser le développeur qui l'a écrit .. Mais alors, je me suis dit que je devrais m'assurer que j'avais raison en premier.

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

Cette ligne va-t-elle jamais être fausse?


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


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


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


Non, ça ne peut pas. Si vous utilisez this , alors vous êtes dans l'instance donc this n'est pas nul.

Le JLS dit:

Lorsqu'il est utilisé en tant qu'expression primaire, le mot clé this 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 invoqué une méthode à partir d'un objet, alors l'objet existe ou vous auriez une NullPointerException avant (ou c'est une méthode statique mais alors, vous ne pouvez pas l'utiliser dedans).

Ressources :


Si vous compilez avec -target 1.3 ou plus tôt, alors un externe this peut être null . Ou au moins, c'était ...


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

Un qualifié this ne devrait jamais être null , mais il est possible de le casser. Considérer ce qui suit:

public class Outer {
   public Outer() {}

   public class Inner {
       public Inner() {}

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

Quand nous voulons créer une instance d' 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 [email protected]
Exception in thread "main" java.lang.NullPointerException
        at Outer.main(Outer.java:19)

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

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

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

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

De toute façon vous le faites, le résultat final est que l'expression Outer.this va évaluer à null 2 .

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

1 - J'écris des astuces telles que «écrire» les bytecodes à la main et les passer comme vrai Java, peaufiner les codes par l'intermédiaire de BCEL ou similaire, ou sauter dans le code natif et tricher avec les registres sauvegardés. OMI, ce n'est pas Java. Hypothétiquement, de telles choses peuvent également survenir à la suite d'un bug JVM ... mais je ne me souviens pas de tous les rapports de bugs.

2 - En fait, le JLS ne dit pas quel sera le comportement, et cela dépendra de l'implémentation ... entre autres choses.


Non jamais , le mot-clé 'this' représente lui-même l'instance active 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 visibles de sa classe parente.

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

this = null;

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

De plus, tenter this = null; se traduira par une erreur de compilation. Reason est assez simple, un mot clé en Java (ou n'importe quelle langue) ne peut jamais être assigné une valeur, c'est-à-dire qu'un mot-clé ne peut jamais être la valeur gauche d'une opération d'assignation.

D'autres exemples, vous ne pouvez pas dire:

true = new Boolean(true);
true = false;






this