Verwenden von "this" mit Klassennamen

115

Ich mache Android-Programmierung und lernte etwas über Absichten, als ich einen Konstruktor sah, der für meinen C # -geschulten Verstand funky wirkte. Der Anruf war:

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

Beide Parameter sind für mich neu. Wie gibt es ein statisches ".this" aus einem Klassennamen? Ist das eine Java-Sache oder eine Android-Sache? Ich gehe davon aus, dass es dasselbe ist, als nur "dies" zu sagen, da ich im Kontext von bin CurrentActivity, aber ich verstehe nicht, wie das "dies" vom Klassennamen selbst abgerufen werden kann. Ebenfalls. Die ".class" scheint für die Reflexion verwendet zu werden, mit der ich in C # vertraut bin, aber jeder Einblick in diese wäre auch willkommen.

Vielen Dank.

skaz
quelle

Antworten:

138

Normalerweise können Sie nur verwenden this. Aber manchmal thiswird auf eine innere Klasse Bezug genommen ... also zum Beispiel:

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
quelle
17
Aha. Hätte ich in Ihrem Beispiel in der neuen Absicht gerade "dies" gesagt, würde dies auf das "dies" der OnClickListener-Klasse verweisen, aber da ich auf die äußere Klasse verweisen muss, brauche ich eine Möglichkeit, dies zu kennzeichnen.
Skaz
7
Richtig. thisist immer die innerste Klasse.
Falmarri
7
Und um den anderen Teil der Frage zu beantworten: Ja, es ist eine Java-Sache
Decko
1
Ich habe mich gefragt, warum MyClass.this und nicht nur dies bei der Registrierung eines Hörers! Danke
luigi7up
3
Komisch! Wer wusste, dass Java thisso sehr JavaScript ähnelt this? Ich denke, das bekommen Sie, wenn Sie keine erstklassigen Funktionen oder Lambdas haben :-)
Pat
61

Eins nach dem anderen:

Das erste Konstrukt wird als qualifiziert bezeichnet . Der Zweck der Syntax liegt in dem Fall, dass Sie sich in einer inneren Klasse befinden (normalerweise einer anonymen inneren Klasse) und auf die thisder äußeren Klasse und nicht auf die thisder (anonymen) inneren Klasse verweisen möchten . Das "qualifizierte Dies" kann nur in einem Kontext verwendet werden, in dem thises nicht eindeutig wäre. Das Zitat des JLS "Es ist ein Fehler zur Kompilierungszeit, wenn der Ausdruck in einer Klasse oder Schnittstelle auftritt, die keine innere Klasse der Klasse T oder T selbst ist."

Das zweite Konstrukt, das als a bezeichnet wird, class literalist die Methode, um auf das Class-Objekt zu verweisen, das diesen Typ darstellt. Es kann in jedem Kontext verwendet werden.

Yishai
quelle
Es ist erwähnenswert, dass diese Antwort nur funktioniert, wenn es eine geschlossene Klasse gibt und Sie auf eine äußere Klasse verweisen, wenn diese Antwort immer noch nicht klar genug ist. Sie können "NotInTheStackOfEnclosings.this" einfach nicht verwenden.
Diego Nonnen
1
@DiegoNunes, das gilt für das qualified thisNicht des class literal. Ich habe meine Antwort erweitert, um dies klarer zu machen.
Yishai
14

Die Syntax "Classname.this" gilt für innere Klassen. Wenn Sie auf die einschließende Instanz vom Typ "Outerclass" verweisen möchten, tun Sie dies als "Outerclass.this".

NextActivity.class ist einfach das Class-Objekt, das die Klasse "NextActivity" beschreibt.

DJClayworth
quelle
11

NextActivity.classin Java bedeutet typeof(NextActivity)in C #

Codymanix
quelle
8

ClassName.this wird verwendet, um auf die aktuelle Instanz einer äußeren Klasse aus einer inneren Klasse zu verweisen.

akf
quelle
Und schon umgekehrt?
Codymanix
5
<ClassName>.this

wird in verschachtelten Klassen verwendet, um auf die aktuelle Instanz der einschließenden Klasse zu verweisen, da das Schlüsselwort "this" auf die Nestklasseninstanz verweist.

öffentliche Klasse Siht { Klasse NestedSiht { void demoThis () { System . err . println ( " Siht.this 'ist eine Instanz von:" + Siht . this . getClass (). getName ());   
      
         
            this' is an instance of: " + 
                            this.getClass().getName());
            System.err.println(" 
                            
        } }
    

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
quelle
0

Es ist verwirrend , nur weil , wenn Sie "verwenden MainActivity.this " anscheinend auf die Klasse und nicht auf das Objekt verweisen. In der Realität beziehen Sie sich bei Verwendung von "this" immer auf das aktuelle Objekt, wie in der Java-Dokumentation angegeben:

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

Innerhalb einer Instanzmethode oder eines Konstruktors ist dies eine Referenz auf das aktuelle Objekt - das Objekt, dessen Methode oder Konstruktor aufgerufen wird. Mit dieser Option können Sie innerhalb einer Instanzmethode oder eines Konstruktors auf ein beliebiges Mitglied des aktuellen Objekts verweisen.

Es ist nur syntaktisch eigenartig.

Gaetano
quelle