Почему «this» неявно передается в качестве параметра при каждой попытке вызова конструктора или метода? - PullRequest
0 голосов
/ 25 октября 2018

Рассмотрим этот блок кода Java.

    Public class MyClass {
       public void method(int a) {
            doSometing() ;
       }
      Public static void main(String[] args) {
          MyClass obj = new MyClass() ;
          int a = 0 ;
          obj.method(a) ; 
     }
    }

Очевидно, в Java, всякий раз, когда вы пытаетесь вызвать конструктор или метод, оказывается, что на самом деле Java неявно передает другое значение, отличное от явного.переданный Разработчиком, который является "этим", и я знаком с понятием "этого" ключевого слова в Java, но я думаю, что избыточно для того, чтобы "это" передавалось методу или конструктору неявно, если ive уже объявил, какой объектэтот метод принадлежит, так почему бы ключевое слово "это" должно быть передано?Итак, в приведенном выше примере Ive объявил класс «MyClass» и метод в этом классе «method» с возвращаемым типом «void», а затем в главной функции im объявил новый экземпляр этого класса «obj» и вызвал метод«method» передает переменную «a» в качестве параметра, так что на самом деле происходит за кулисами, что при объявлении нового экземпляра класса и вызове его конструктора на самом деле неявно передается параметр, который является «this»ключевое слово, так вот как это на самом деле выглядит за кулисами:

MyClass obj = new MyClass(this) ;

и то же самое применяется при вызове метода:

obj.method(this,a) ;

Вот так, пожалуйста, кто-нибудь может мне помочьс этим, потому что я пытаюсь выучить Java, и мне нужно убедиться, что мне все ясно, прежде чем я перейду к дополнительным темам

Спасибо

Ответы [ 2 ]

0 голосов
/ 26 октября 2018

Я полагаю, что вы ищете следующее: все (?) Языки программирования OO реализуются передачей «this» в качестве параметра каждой функции, содержащейся в классе.Различия в языках заключаются в том, как реализована эта «функциональность».

В Python функции просто определяются как функции, и вы передаете «this» в качестве первого параметра.

Большинство других языков OO скрывают »это ", когда они передают это, но это все еще там - это должно быть.Вы можете думать о передаче «this» как о разнице между методом и функцией.

0 голосов
/ 26 октября 2018

Вероятно, самый прямой способ понять , почему вам необходимо неявно передавать ссылку this на каждую нестатическую функцию, которую вы вызываете, чтобы показать вам, как такой вызов функции работает «под капотом»..

Давайте рассмотрим простой пример, например

class Test {
    public void foo(int arg) {}
    public static void bar(int arg) {}
    public void baz() {
        foo(1);
        bar(2);
    }
}

В чем разница между foo и bar?
Нестатическая функция foo выполняется вконтекст объекта, в то время как у статического bar такого контекста нет.Это означает, что foo сможет читать и записывать любые поля внутри этого объекта, bar не будет.

В то время как Java как язык знает о контексте любой функции, которую вы вызываете, виртуальная машина Java(JVM), которая на самом деле выполняет код, напрямую не различает статические и нестатические функции и не знает контекстов вызовов.(Да, это немного вопрос семантики, поскольку он различает статическое и динамическое связывание, которое в основном совпадает со статическими / нестатическими функциями)

Поэтому, когда вы вызываете нестатический метод,контекст вызова (т. е. объект, для которого вызывается метод) должен быть предоставлен как неявный параметр, который называется this.

Байт-код JVM для приведенного выше примера будет следующим:

public void baz();
Code:
   0: aload_0           // Push 'this' as the first parameter onto the stack
   1: iconst_1          // Push 1 as the second parameter onto the stack
   2: invokevirtual #2  // Call 'foo'
   5: iconst_2          // Push 2 as the first parameter onto the stack
   6: invokestatic  #3  // Call 'bar'
   9: return 

Вы видите, что для статической функции вы только помещаете параметр в стек (который затем извлекается последующим вызовом), для нестатических функций вы сначала помещаете this в стек, которыйбыл также первым аргументом вызова функции baz (aload обозначает аргумент load )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...