2014-11-26 28 views
15

qual è il significato di "this.this $ 0" in questo codice? cosa significa? Io so perché usiamo "questo", ma non ho idea di "this.this $ 0"

class MainActivity$1 implements TextWatcher 
{ 
    public void afterTextChanged(Editable paramEditable) 
    { 
    } 

    public void beforeTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3) 
    { 
    } 

    public void onTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3) 
    { 
    this.this$0.ChangeToNumber(paramCharSequence.toString()); 
    } 
} 
-----------------------or ---------------------- 
class MainActivity$2 implements View.OnClickListener 
{ 
    public void onClick(View paramView) 
    { 
    this.this$0.startActivity(new Intent(this.this$0, about.class)); 
    } 
} 

risposta

14

this.this $ 0 è uguale a Main.access $ 0 Questi misteriosi simboli di solito corrispondono alle classi interne anonime. La Java VM non ne sa nulla, solo sulle classi di primo livello, quindi il compilatore Java offre diversi metodi per far funzionare le classi interne.

La classe locale ha un riferimento implicito all'istanza della sua classe di inclusione, "questo $ 0" corrisponde a questo riferimento nel codice decompilato. JVM impedisce alle classi di accedere ai metodi privati ​​di altre classi, in modo che il compilatore generi diversi metodi sintetici per i pacchetti privati ​​come l'accesso $ 0 per accedere ai metodi privati ​​di istanza che li include.

Ci sono molte altre funzionalità del linguaggio Java che sono implementate con metodi sintetici come generici e tipi di ritorno covarianti.

suggerisco di controllare quei link: Decoding Decompiled Source Code For Android

e: Performance Tips

3

Non c'è niente impedisce che si (accanto a convenzioni di denominazione decenti) di avere un membro di istanza chiamato this$0 e poi riferendosi ad essa con la parola chiave this.

Ad esempio:

public class SomeClass 
{ 
    int this$0; 
    public SomeClass (int val) 
    { 
     this.this$0 = val; 
    } 
} 
2

Java 1.1 Language Specification specifica che il nome di un tipo che è un membro della classe, quando trasforma in codice Java 1.0 lo scopo di generare bytecode di macchine virtuali Java è costituito dal nome completo della classe interna, ad eccezione di ogni .' character following a class name is replaced by a $ '. Inoltre, ogni costruttore di classi interne riceve l'istanza allegata in un argomento anteposto. Ecco come il codice sorgente trasformato dell'esempio FixedStack potrebbe apparire:

codice
public class FixedStack { 
     ... (the methods omitted here are unchanged) 
     public java.util.Enumeration elements() { 
      return new FixedStack$Enumerator(this); 
     } 
    } 

    class FixedStack$Enumerator implements java.util.Enumeration { 
     private FixedStack this$0; // saved copy of FixedStack.this 
     FixedStack$Enumerator(FixedStack this$0) { 
      this.this$0 = this$0; 
      this.count = this$0.top; 
     } 

     int count; 
     public boolean hasMoreElements() { 
      return count > 0; 
     } 
     public Object nextElement() { 
      if (count == 0) 
       throw new NoSuchElementException("FixedStack"); 
      return this$0.array[--count]; 
     } 
    } 

Chi ha già programmato con Java o C++ classi adattatore ha scritto simile a questo, se non che le variabili di collegamento devono essere definite manualmente e in modo esplicito inizializzato nelle classi dell'adattatore di primo livello, mentre il compilatore Java 1.1 le crea automaticamente per le classi interne.

Quando l'enumeratore deve fare riferimento ai campi superiore o di matrice dell'istanza che lo include, viene indiretto tramite un collegamento privato denominato $ 0. L'ortografia di questo nome è una parte obbligatoria della trasformazione delle classi interne nel linguaggio Java 1.0, in modo che i debugger e strumenti simili possano riconoscere facilmente tali collegamenti. (La maggior parte dei programmatori è felicemente inconsapevole di tali nomi.)

(Nota: esiste una limitazione in alcune implementazioni di Java 1.1, in base alle quali l'inizializzazione di $ 0 viene ritardata fino a quando non viene eseguito alcun costruttore di superclasse. i riferimenti di livello fatti da un metodo di sottoclasse possono fallire se il metodo viene eseguito dal costruttore della superclasse.)