Utiliser «ceci» avec le nom de la classe

115

Je fais de la programmation Android et j'apprenais les intentions, quand j'ai vu un constructeur qui, à mon esprit formé à C #, semblait génial. L'appel était:

Intent myIntent = new Intent(CurrentActivity.this, NextActivity.class);

Les deux paramètres sont nouveaux pour moi. Comment y a-t-il un ".this" statique hors d'un nom de classe? Est-ce une chose Java ou une chose Android? Je suppose que c'est la même chose que de simplement dire «ceci», puisque je suis dans le contexte de CurrentActivity, mais je ne comprends pas comment le «ceci» peut être annulé du nom de la classe lui-même. Aussi. Le ".class" semble être utilisé pour la réflexion, ce que je connais bien en C #, mais tout aperçu à ce sujet serait également le bienvenu.

Merci.

skaz
la source

Réponses:

138

Habituellement, vous ne pouvez utiliser que des fichiers this. Mais, thisfait parfois référence à une classe interne ... alors, par exemple:

Button button = (Button)findViewById(R.id.ticket_details_sell_ticket);
button.setOnClickListener(new OnClickListener() {
    @Override
    public void onClick(View v) {
        // it will be wrong to use only "this", because it would
        // reference the just created OnClickListener object
        Intent login = new Intent(ClassName.this, Login.class);
        startActivityForResult(login, LOGIN_REQUEST);
    }
});
Cristian
la source
17
Je vois. Donc, si je venais de dire «ceci» dans le nouvel Intent de votre exemple, cela ferait référence au «ceci» de la classe OnClickListener, mais comme j'ai besoin de faire référence à la classe externe, j'ai besoin d'un moyen de le signifier.
skaz
7
Droite. thisest toujours la classe la plus intime.
Falmarri
7
Et pour répondre à l'autre partie de la question: oui, c'est une chose java
Decko
1
Je me demandais pourquoi MyClass.this et pas seulement cela lors de l'inscription d'un auditeur! Merci
luigi7up
3
Drôle! Qui savait que Java thisressemblait tellement à JavaScript this? Je suppose que c'est ce que vous obtenez pour ne pas avoir de fonctions de première classe ou de lambdas :-)
Pat
61

Un à la fois:

La première construction est appelée un ceci qualifié . Le but de la syntaxe est dans le cas où vous êtes dans une classe interne (généralement une classe interne anonyme) et que vous souhaitez référencer la thisclasse externe plutôt que la thisclasse interne (anonyme). Le "qualifié ceci" ne peut être utilisé que dans un contexte où il thisserait ambigu. La citation du JLS "C'est une erreur de compilation si l'expression se produit dans une classe ou une interface qui n'est pas une classe interne de la classe T ou T elle-même".

La deuxième construction est appelée a class literalest le moyen de référencer l'objet Class qui représente ce type. Il peut être utilisé dans n'importe quel contexte.

Yishai
la source
Il est intéressant de noter, si cette réponse n'est toujours pas assez claire, qu'elle ne fonctionne que lorsqu'il y a une classe incluse et que vous faites référence à une classe externe. Vous ne pouvez tout simplement pas utiliser "NotInTheStackOfEnclosings.this".
diego nunes
1
@DiegoNunes, c'est vrai du qualified thisnon du class literal. J'ai développé ma réponse pour que cela soit plus clair.
Yishai
14

La syntaxe "Classname.this" est pour les classes internes. Si vous voulez faire référence à l'instance englobante de type "Outerclass", vous le faites comme "Outerclass.this".

NextActivity.class est simplement l'objet Class qui décrit la classe "NextActivity".

DJClayworth
la source
11

NextActivity.classen java signifie typeof(NextActivity)en C #

codymanix
la source
8

ClassName.this est utilisé pour référencer l'instance actuelle d'une classe externe à partir d'une classe interne.

akf
la source
Et certainement l'inverse?
codymanix
5
<ClassName>.this

est utilisé dans les classes imbriquées pour faire référence à l'instance actuelle de la classe englobante, puisque le mot clé `this 'fait référence à l'instance de la classe nest.

public class Siht { classe Siht {  
    class NestedSiht {class NestedSiht {  
        void demoThis () {void demoThis () { 
            System.err.println (" Siht.this 'est une instance de:" +Système . euh . println ( " +this' is an instance of: " + 
                            this.getClass().getName());
            System.err.println(" 
                            Siht.this.getClass (). GetName ());Siht . ceci . getClass (). getName ());
        }}
    }}

void demoThis() {
    new java.lang.Object() {
        void demoThis() {
            System.err.println("`this' is an instance of: " + 
                            this.getClass().getName());
            System.err.println("`Siht.this' is an instance of: " +
                            Siht.this.getClass().getName());
        }
    }.demoThis();
    new NestedSiht().demoThis();
}

public static void main(String [] args) {
    new Siht().demoThis();
}

}

Khachik
la source
0

C'est déroutant uniquement parce que lorsque vous utilisez " MainActivity.this ", il semble que vous faites référence à la classe et non à l'objet. En réalité, lorsque vous utilisez "this", vous faites toujours référence à l'objet actuel, comme l'indique la documentation java se:

https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html

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 actuel à partir d'une méthode d'instance ou d'un constructeur en utilisant this.

C'est juste syntaxiquement particulier.

Gaetano
la source