如果我们声明一个对象并将其分配给相同 class 的另一个对象会发生什么
What will happen if we declare one object and assign it to another object of same class
C++ 代码
class FirstClass
{
public:
int var;
};
int main()
{
FirstClass A, B;
A.var = 10;
B.var = 20;
cout << "Address of A : " << &A << endl;
cout << "A.var : " << A.var << endl << endl;
cout << "Address of B : " << &B << endl;
cout << "B.var : " << B.var << endl << endl;
A = B;
cout << "Address of A : " << &A << endl;
cout << "A.var : " << A.var << endl << endl;
cout << "Address of B : " << &B << endl;
cout << "B.var : " << B.var << endl << endl;
}
输出:
A 的地址:0x28fefc
A.var : 10
B地址:0x28fef8
B.var : 20
A 的地址:0x28fefc
A.var : 20
B地址:0x28fef8
B.var : 20
我知道内存和 var 的值是怎么回事。不要与上面的代码混淆。重点是内存保持不同并且两个对象仍然引用相同的旧内存位置。意味着没有未引用的内存。
Java中的代码;
public class FirstClass
{
public int var;
}
public class SecondClass
{
public static void main(String str[])
{
FirstClass A = new FirstClass();
FirstClass B = new FirstClass();
A = B;
}
}
做我在上面的 C++ 代码中做的同样的事情。
为什么这次垃圾收集器会起作用,通过执行 A = B 为什么我们会得到未引用的内存。
这是C++和Java的区别之一。当您在 C++ 中将一个对象分配给另一个对象时,它会将一个对象的值复制到另一个对象。而在 Java 中,它会将 A 声明为对 B 指向的对象的引用。由于现在 JVM 已丢失对 B 的引用并且无法访问,因此它成为 GC 的合格候选者。
让我们更改您的代码以提供更多上下文:
FirstClass A = new FirstClass(1);
FirstClass B = new FirstClass(2);
此时,FirstClass(1)
和 FirstClass(2)
不符合 GC 的条件,因为范围内有两个变量当前指向这些实例。但是,当您执行该行时:
A = B;
你让 A
和 B
指向 FirstClass(2)
并且 "nothing" 指向 FirstClass(1)
... 因为有 "nothing" 指向为此,FirstClass(1)
有资格进行 GC。
Java中的变量有两种。它们要么是原始类型(例如 int
、boolean
),要么是 Object
类型。原始值总是在赋值时被复制,但对象变量就像 C++ 中的指针一样。如果您将一个 Object 变量分配给另一个,那么您只是更改它指向的内存位置,而不是创建目标的新 "copied" 实例。
在Java中,A
和B
实际上是指针。但在您的 C++ 代码中,它们不是。这是唯一的区别。
如果将 C++ A
和 B
更改为指针,您会发现这两段代码现在是等价的:
FirstClass* A = new FirstClass;
FirstClass* B = new FirstClass;
A->var = 10;
B->var = 20;
A = B;
现在 A = B
复制指针,而不是指向的对象,就像在 Java 中一样。
java
中的简单对象创建
SomeClass obj = new SomeClass();
当你在java中使用new
关键字创建一个新对象时,如上所示,JVM在堆区分配所需的内存并将该内存区分配给给定的引用变量,obj
在我们的例子中。因此,在您的情况下,它为 2 个对象分配内存并将引用分配给相应的引用变量。
当你在做的时候
A = B;
我们正在指示JVM分配内存引用,B引用变量A。所以,现在A和B都指向同一个内存区域。另一个内存区域(在执行赋值语句之前实际上由 A 指向)没有被任何引用指向,因此符合垃圾收集条件
C++ 代码
class FirstClass
{
public:
int var;
};
int main()
{
FirstClass A, B;
A.var = 10;
B.var = 20;
cout << "Address of A : " << &A << endl;
cout << "A.var : " << A.var << endl << endl;
cout << "Address of B : " << &B << endl;
cout << "B.var : " << B.var << endl << endl;
A = B;
cout << "Address of A : " << &A << endl;
cout << "A.var : " << A.var << endl << endl;
cout << "Address of B : " << &B << endl;
cout << "B.var : " << B.var << endl << endl;
}
输出:
A 的地址:0x28fefc
A.var : 10
B地址:0x28fef8
B.var : 20
A 的地址:0x28fefc
A.var : 20
B地址:0x28fef8
B.var : 20
我知道内存和 var 的值是怎么回事。不要与上面的代码混淆。重点是内存保持不同并且两个对象仍然引用相同的旧内存位置。意味着没有未引用的内存。
Java中的代码;
public class FirstClass
{
public int var;
}
public class SecondClass
{
public static void main(String str[])
{
FirstClass A = new FirstClass();
FirstClass B = new FirstClass();
A = B;
}
}
做我在上面的 C++ 代码中做的同样的事情。 为什么这次垃圾收集器会起作用,通过执行 A = B 为什么我们会得到未引用的内存。
这是C++和Java的区别之一。当您在 C++ 中将一个对象分配给另一个对象时,它会将一个对象的值复制到另一个对象。而在 Java 中,它会将 A 声明为对 B 指向的对象的引用。由于现在 JVM 已丢失对 B 的引用并且无法访问,因此它成为 GC 的合格候选者。
让我们更改您的代码以提供更多上下文:
FirstClass A = new FirstClass(1);
FirstClass B = new FirstClass(2);
此时,FirstClass(1)
和 FirstClass(2)
不符合 GC 的条件,因为范围内有两个变量当前指向这些实例。但是,当您执行该行时:
A = B;
你让 A
和 B
指向 FirstClass(2)
并且 "nothing" 指向 FirstClass(1)
... 因为有 "nothing" 指向为此,FirstClass(1)
有资格进行 GC。
Java中的变量有两种。它们要么是原始类型(例如 int
、boolean
),要么是 Object
类型。原始值总是在赋值时被复制,但对象变量就像 C++ 中的指针一样。如果您将一个 Object 变量分配给另一个,那么您只是更改它指向的内存位置,而不是创建目标的新 "copied" 实例。
在Java中,A
和B
实际上是指针。但在您的 C++ 代码中,它们不是。这是唯一的区别。
如果将 C++ A
和 B
更改为指针,您会发现这两段代码现在是等价的:
FirstClass* A = new FirstClass;
FirstClass* B = new FirstClass;
A->var = 10;
B->var = 20;
A = B;
现在 A = B
复制指针,而不是指向的对象,就像在 Java 中一样。
java
中的简单对象创建SomeClass obj = new SomeClass();
当你在java中使用new
关键字创建一个新对象时,如上所示,JVM在堆区分配所需的内存并将该内存区分配给给定的引用变量,obj
在我们的例子中。因此,在您的情况下,它为 2 个对象分配内存并将引用分配给相应的引用变量。
当你在做的时候
A = B;
我们正在指示JVM分配内存引用,B引用变量A。所以,现在A和B都指向同一个内存区域。另一个内存区域(在执行赋值语句之前实际上由 A 指向)没有被任何引用指向,因此符合垃圾收集条件