为什么在尝试调用构造函数或方法时将“ this”作为参数隐式传递?

时间:2018-10-25 20:29:10

标签: java oop

考虑此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传递,而不是由开发人员传递的显式传递,即“ this”,我熟悉Java中“ this”关键字的概念,但我认为将“ this”传递给方法或如果ive已经声明了此方法属于哪个对象,则隐式构造函数,那么为什么必须传递关键字“ this”呢?因此,在上面的示例中,Ive声明了一个类“ MyClass”,并在该类“方法”中声明了一个返回类型为“ void”的方法,然后在主函数中声明了该类“ obj”的新实例并调用了该方法“方法”将变量“ a”作为参数传递,因此在幕后发生的实际情况是,在声明一个类的新实例并调用其构造函数时,实际上隐式传递了一个参数,即“ this”关键字,这就是幕后的真实样子:

MyClass obj = new MyClass(this) ;

调用方法时同样适用:

obj.method(this,a) ;

就是这样,所以请任何人帮助我在那儿尝试Java,并且在我继续进行“高级主题”之前,我需要确保一切对我来说都是清楚的

谢谢

2 个答案:

答案 0 :(得分:3)

我相信您正在寻找的是:通过将“ this”作为参数传递给类中包含的每个函数来实现所有(?)OO编程语言。语言上的差异在于该功能的实现方式。

在Python中,函数只是定义为函数,您将“ this”作为第一个参数传递。

大多数其他的OO语言在通过它时都会隐藏“ this”,但是它仍然存在-必须存在。您可以将“ this”的传递视为方法和函数之间的区别。

答案 1 :(得分:1)

了解为什么的最直接方法可能是需要向您调用的每个非静态函数隐式传递this引用,以向您展示该函数如何在引擎盖”。

让我们举一个简单的例子

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

现在foobar有什么区别?
非静态函数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代表 argument load