Java中的实例方法调用

Java中的实例方法调用,java,Java,在Java中,为每个对象创建一个实例变量的新副本,可以使用对象引用访问该副本。 但对于实例方法,它只存在一个副本(实例方法)。 各种对象引用如何访问此方法?该方法的字节码(或本机代码,如果是JIT'd)存储在一个位置。调用该方法时,会将指向实例对象的指针(在引擎盖下,也称为更高级别的引用)作为第一个参数传递,以便方法代码可以在该特定实例上操作-可以访问其字段等,以节省空间而不增加性能成本,java中的调用机制比C++复杂得多,尤其是对于接口方法。 方法中的字节码(或如果是JIT)的本地代码存储在

在Java中,为每个对象创建一个实例变量的新副本,可以使用对象引用访问该副本。 但对于实例方法,它只存在一个副本(实例方法)。
各种对象引用如何访问此方法?

该方法的字节码(或本机代码,如果是JIT'd)存储在一个位置。调用该方法时,会将指向实例对象的指针(在引擎盖下,也称为更高级别的引用)作为第一个参数传递,以便方法代码可以在该特定实例上操作-可以访问其字段等,以节省空间而不增加性能成本,java中的调用机制比C++复杂得多,尤其是对于接口方法。

方法中的字节码(或如果是JIT)的本地代码存储在一个位置。调用该方法时,会将指向实例对象的指针(在引擎盖下,也称为更高级别的引用)作为第一个参数传递,以便方法代码可以在该特定实例上操作-可以访问其字段等,以节省空间而不增加性能成本,java中的调用机制比C++复杂得多,尤其是对于接口方法。

方法和字段完全不同。方法应用于对象的所有实例,但字段是针对每个实例的

一种想法是:
假设该方法对所有实例都是“全局的”,但它通过“this”引用“传递”了对象的实例


方法可以更改特定实例的状态,但它们本身是无状态的。

方法和字段完全不同。方法应用于对象的所有实例,但字段是针对每个实例的

一种想法是:
假设该方法对所有实例都是“全局的”,但它通过“this”引用“传递”了对象的实例

方法可以更改特定实例的状态,但它们本身是无状态的。

与以前的

我确信实际的实现是完全不同的,但是让我解释一下我的方法分派的概念,它精确地模拟了观察到的行为

假设每个类都有一个哈希表,该哈希表将方法签名(名称和参数类型)映射到实现该方法的实际代码块。当虚拟机尝试调用实例上的方法时,它会获取对象的类,并在类的表中查找请求的签名。如果找到一个方法体,就会调用它,将原始对象作为名为
this
的引用

否则,将获得该类的父类,并在此重复查找。这将一直进行,直到找到该方法,或者不再存在导致
NoSuchMethodError
的父类

如果一个超类和一个子类在它们的表中都有一个相同方法签名的条目,那么首先会遇到子类的版本,并且从不使用该超类的版本。这是一个“覆盖”。

来自上一个

我确信实际的实现是完全不同的,但是让我解释一下我的方法分派的概念,它精确地模拟了观察到的行为

假设每个类都有一个哈希表,该哈希表将方法签名(名称和参数类型)映射到实现该方法的实际代码块。当虚拟机尝试调用实例上的方法时,它会获取对象的类,并在类的表中查找请求的签名。如果找到一个方法体,就会调用它,将原始对象作为名为
this
的引用

否则,将获得该类的父类,并在此重复查找。这将一直进行,直到找到该方法,或者不再存在导致
NoSuchMethodError
的父类


如果一个超类和一个子类在它们的表中都有一个相同方法签名的条目,那么首先会遇到子类的版本,并且从不使用该超类的版本,这是一个“重写”。

隐含的引用“this”会传递给每个方法,当然,您可以显式地引用它。隐含的引用“this”传递给每个方法,当然,您可以在幕后显式地引用它。对对象的引用作为调用的一部分传递给方法。特别是查看Java的反射类可能很有用。

在幕后,对象的引用作为调用的一部分传递给方法。特别是查看Java的反射类可能会很有用。

我假设您的意思过于简单,就像您实际如何执行调用一样。 我还假设您引用的方法在其签名中有
static
修饰符,即:

public static int getNum() 
{
  // code in here 
  return num;
}
如果这就是您的意思,并且它是名为“
SomeClass
”的类的一部分,那么可以通过方法调用
SomeClass.getNum()
来访问它。即,将实际的类名放在方法之前


如果这不是你的意思,请忽略我的回答:)

我假设你的意思过于简单,比如你实际上是如何打电话的。 我还假设您引用的方法在其签名中有
static
修饰符,即:

public static int getNum() 
{
  // code in here 
  return num;
}
如果这就是您的意思,并且它是名为“
SomeClass
”的类的一部分,那么可以通过方法调用
SomeClass.getNum()
来访问它。即,将实际的类名放在方法之前

如果这不是您的意思,请忽略我的回答:)

“正常”接口调度使用的实现与此类似。哈希表中的键是正在实现的接口方法,值是实现方法。研究人员已经提出了一些巧妙的(甚至更复杂的)方法来显著降低接口调度开销。可以处理虚拟调度