Что означает "this.this $0"?

какой смысл "this.this $0" в этом коде? что это означает? Я знаю, почему мы используем "this", но я понятия не имею о "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));
  }
}

Ответы

Ответ 1

this.this $0 он одинаковый для Main.access $0 Эти таинственные символы обычно соответствуют анонимным внутренним классам. Java VM не знает о них, только о классах верхнего уровня, поэтому компилятор Java предоставляет несколько обходных решений, чтобы заставить внутренние классы работать.

Локальный класс имеет неявную ссылку на экземпляр своего охватывающего класса, 'this $0' соответствует этой ссылке в декомпилированном коде. JVM запрещает классам получать доступ к приватным методам других классов, поэтому компилятор генерирует несколько синтетических пакетов-частных методов, таких как доступ к $0, чтобы получить доступ к закрытым методам включения экземпляра.

Есть много других функций языка Java, которые реализованы с использованием синтетических методов, таких как дженерики и ковариантные типы возвращаемых данных.

Я предлагаю вам проверить эти ссылки: Декодирование декомпилированного исходного кода для Android

и: Рекомендации по производительности

Ответ 2

Ничего не мешает вам (помимо обычных соглашений об именах) иметь экземпляр-член с именем this$0, а затем ссылаться на него с ключевым словом this.

Например:

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

Ответ 3

Спецификация языка Java 1.1 указывает, что имя типа, являющегося членом класса, при преобразовании в код Java 1.0 с целью генерации байт-кодов виртуальной машины Java состоит из полного имени внутреннего класса, за исключением того, что каждый .' character following a class name is replaced by a $'. Кроме того, каждый внутренний конструктор класса получает экземпляр окружения в дополнительном аргументе. Вот как выглядит преобразованный исходный код примера FixedStack:

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];
        }
    }

Любой, кто уже запрограммирован с классами адаптеров Java или С++, написал код, подобный этому, за исключением того, что переменные ссылки должны быть определены вручную и явно инициализированы в классах адаптеров верхнего уровня, тогда как компилятор Java 1.1 автоматически создает их для внутреннего классы.

Когда Enumerator должен ссылаться на верхние или массивные поля экземпляра-экземпляра, он косвенным образом связан с частной ссылкой, называемой этим $0. Написание этого имени является обязательной частью преобразования внутренних классов на язык Java 1.0, так что отладчики и подобные инструменты могут легко распознавать такие ссылки. (Большинство программистов счастливо не знают о таких именах.)

(Примечание. В некоторых реализациях Java 1.1 существует ограничение, при котором инициализация этого $0 задерживается до тех пор, пока не будет запущен какой-либо конструктор суперкласса. Это означает, что ссылки верхнего уровня, сделанные методом подкласса, могут не работать, если метод выполняется конструктором суперкласса.)