Java 为什么是;这";在试图调用构造函数或方法时作为参数隐式传递?
考虑这段java代码Java 为什么是;这";在试图调用构造函数或方法时作为参数隐式传递?,java,oop,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) ;
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”传递给方法或构造函数是多余的,那么为什么关键字“this”必须通过吗,因此,在上面的示例中,我声明了一个类“MyClass”,该类中的一个方法“method”,返回类型为“void”,然后在主函数中,我声明了该类的一个新实例“obj”,并调用方法“method”,将变量“a”作为参数传递,因此,在幕后实际发生的事情是,当声明一个类的新实例并调用它的构造函数时,实际上有一个隐式传递的参数,即“this”关键字,所以这就是它在幕后的真实情况:
MyClass obj = new MyClass(this) ;
调用该方法时,同样的情况也适用:
obj.method(this,a) ;
就这样,请任何人帮我学习java,因为我想学习java,在我继续学习高级主题之前,我需要确保一切都清楚
谢谢理解为什么需要隐式传递
此
引用到您调用的每个非静态函数,最直接的方法可能是向您展示这种函数调用是如何“在引擎盖下”工作的
让我们举一个简单的例子,比如
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
表示参数加载)理解为什么需要隐式传递此
引用到您调用的每个非静态函数的最直接方法可能是向您展示这种函数调用是如何“在引擎盖下”工作的
让我们举一个简单的例子,比如
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
表示参数加载)我相信您想要的是:所有(?)OO编程语言都是通过将“this”作为参数传递给类中包含的每个函数来实现的。两种语言的区别在于如何实现这种功能
在Python中,函数只是定义为函数,您将“this”作为第一个参数传递
大多数其他OO语言在传递时都会隐藏“this”,但它仍然存在——它必须存在。你可以把传递“this”看作是方法和函数之间的区别。我相信你想要的是:所有(?)OO编程语言都是通过将“this”作为参数传递给类中包含的每个函数来实现的。两种语言的区别在于如何实现这种功能 在Python中,函数只是定义为函数,您将“this”作为第一个参数传递
大多数其他OO语言在传递时都会隐藏“this”,但它仍然存在——它必须存在。您可以将“this”的传递视为方法和函数之间的区别。为什么不给出一个examole场景?将其作为参数传递是什么意思?你是说obj.method(par,this)是JVM如何处理这个方法的?您在哪里读到“this”作为另一个参数传递?我想你看错了