在Java类中,我们是否为该类的每个对象都有单独的实例方法副本?

时间:2017-09-05 12:05:45

标签: java

如果不是,运行时如何,实例方法是否使用同一对象的实例变量? 例如,我有 A类,具有实例变量aVariable和非静态方法aMethod()。现在我有一个 A类的对象,让它命名为aObject。 aMethod使用aVariable。当我调用这个方法时,它如何知道在内存中使用哪个aVariable以及它存储在哪里?我们是否将所有对象信息传递给方法? 请帮帮我。

5 个答案:

答案 0 :(得分:6)

请参阅JVM Spec, Sec 3.7

int add12and13() {
    return addTwo(12, 13);
  }
     

这编译为:

Method int add12and13()
0   aload_0             // Push local variable 0 (this)
1   bipush 12           // Push int constant 12
3   bipush 13           // Push int constant 13
5   invokevirtual #4    // Method Example.addtwo(II)I
8   ireturn             // Return int on top of operand stack;
                        // it is the int result of addTwo()
     

通过首先将对当前实例的引用推送到操作数堆栈来设置调用。然后推送方法调用的参数,int值12和13。

因此,this引用(或接收器参数的任何其他值)只是作为另一个参数被压入堆栈。因此,每个实例不需要单独的方法副本。

答案 1 :(得分:2)

不,我们没有单独的副本用于实例方法。 这样做的方法是将隐含的引用传递给this

方法

public void doSomething(Object param);

,致电

this.doSomething(myParameter);

已解决

doSomething(this, myParameter);

答案 2 :(得分:1)

它使用该类的特定实例的实例方法:

public class Person{
  private String name;
  public Person(String name){
    this.name = name;
  }

  public void printName(){
    System.out.println(name);
    System.out.println(this.name);
  }
}

此处printName使用name变量。假设我们有两个Person

的实例
Person a = new Person("Andrew");
Person b = new Person("Bert");

当您在这些实例的(y)上调用实例成员时,该实例不知道除了自身之外的任何其他实例,因此,如果您调用a.printName()它将始终打印安德鲁,因为这是名称存储在变量中,如果你调用b.printName(),它将始终打印Bert。

正如您所看到的,添加this.并不会改变printName方法中的任何内容,只有在存在歧义时才需要它,因为存在一个具有相同名称的局部变量。

但它始终会从当前实例中获取值。

答案 3 :(得分:0)

创建对象“aObject”并使用 aObject.aMethod()调用该方法时,使用“aObject”,您可以在其中指定要在该方法上调用该方法的实例!

显然,当您创建多个实例时,您会创建多个内存分配,这些分配位于不同的位置。

实例变量只是一个链接或指向内存位置的指针,其中存储了该实例的所有相关数据。

答案 4 :(得分:0)

首先,您应该了解在创建对象的新实例时内存的工作原理。总结一下,当你创建一个对象的新实例时,它会在内存中创建空间,以便为实例分配整个堆栈中的所有变量。很容易找到它在互联网上的确切运作方式,但这可以作为一个基本的解释。

重要的是要知道,还有其他变量不能以这种方式运作。例如,存在静态变量,其行为方式是,如果更改此变量的值,它将在对象的所有实例中更改。

但总的来说,你必须想象一个对象的变量堆栈,它将构成一个实例,以及那些将构成最终程序的实例的堆栈