本地变量、对象引用及其内存分配

5
我有以下代码块:
class Student{

int age;               //instance variable
String name;     //instance variable

public Student()
 {
    this.age = 0;
    name = "Anonymous";
 }
public Student(int Age, String Name)
 {
    this. age = Age;
    setName(Name);
 }
public void setName(String Name)
 {
    this.name = Name;
 }
}

public class Main{
public static void main(String[] args) {
        Student s;                           //local variable
        s = new Student(23,"Jonh");
        int noStudents = 1;          //local variable
 }
}

我的问题与局部变量和实例变量有关,为了知道它们分配在堆内存还是栈内存中。在默认构造函数中,似乎只存在一个局部变量,即由'this'关键字创建的变量,但是为什么'name = "Anonymous";'不被视为局部变量呢?它是对象类型,但这些也可以是局部变量,对吗?顺便问一下,你能给出使用默认构造函数创建/实例化的对象的示例吗? 谢谢!

1
可能是JVM - 堆和栈的重复问题。 - Makoto
2个回答

9
简而言之,任何类型的名称都只存储引用,它们不直接存储对象。
完全限制在代码块中的名称已经为引用分配了存储空间,在堆栈帧上,该堆栈是线程私有的。
作为类成员的名称已经在堆中为引用分配了存储空间,该堆位于表示该类实例的对象内部。
作为类对象的静态成员的名称已经在堆中为引用分配了存储空间,该堆位于表示该类对象的对象内部。
所有对象都存储在堆上;但是,对它们的引用可能存储在堆上的其他对象内部,也可能存储在堆上的引用占位符内部。
所有基本数据类型都存储在引用应存储的位置。
class Student {

  int age;         // value stored on heap within instance of Student
  String name;     // reference stored on heap within instance of Student

  public Student() {
    this.age = 0;
    name = "Anonymous";
  }

  public Student(int Age, String Name) {
    this.age = Age;
    setName(Name);
  }

  public void setName(String Name) {
    this.name = Name;
  }

}

public class Main {
  public static void main(String[] args) {
        Student s;                    // reference reserved on stack
        s = new Student(23, "John");  // reference stored on stack, object allocated on heap
        int noStudents = 1;           // value stored on stack
  }
}

我认为这可能是一个非常愚蠢的问题/疑问,但当你说“一个类的成员名称在堆中分配了引用的存储”时,这是否适用于name =“Anonymous”?以下是一个生存在堆栈中的引用占位符吗? s = new Student(23, "John"); - csbl
这不是一个愚蠢的问题。"匿名"类是一个类,因此它被分配在堆上;然而,堆保存的信息不能与特定类型绑定,因为它是从抽象类型指定并填充抽象部分的代码。有时,匿名类绑定到名称,其他时候,类直接使用而没有中间名称;但是,该类从未被赋予自己独特的基础类型。 - Edwin Buck

-1

所有基本数据类型(int、double、boolean)创建在栈上。 使用“new”关键字分配的更复杂的对象在堆上,而您的变量仅是指向它的引用(指针)。

局部变量是存在于特定作用域中的变量,例如“Student s”仅存在于Main方法中(它可以存在于栈中或堆中)。


不,这并不完全正确。请检查重复链接。 - Makoto

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接