Что означает "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 задерживается до тех пор, пока не будет запущен какой-либо конструктор суперкласса. Это означает, что ссылки верхнего уровня, сделанные методом подкласса, могут не работать, если метод выполняется конструктором суперкласса.)