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为什么我们会得到一个未引用的记忆。
答案 0 :(得分:3)
让我们更改您的代码只是为了提供更多背景信息:
FirstClass A = new FirstClass(1);
FirstClass B = new FirstClass(2);
此时,FirstClass(1)
和FirstClass(2)
不符合GC的条件,因为范围内有两个当前指向这些实例的变量。但是,当您执行以下行时:
A = B;
你使A
和B
指向FirstClass(2)
和&#34;没有&#34;指向FirstClass(1)
...因为那里没有&#34;没有&#34;指向它,FirstClass(1)
有资格获得GC。
Java中的变量有两种。它们既可以是原始类型(例如int
,boolean
),也可以是Object
类型。原始值总是在赋值时复制,但对象变量就像C ++中的指针一样。如果您将一个Object变量分配给另一个变量,那么您只需更改它指向的内存位置,而不是创建一个新的&#34;复制的&#34;目标的实例。
答案 1 :(得分:2)
这是C ++和Java的不同之处。在C ++中将一个对象分配给另一个对象时,它会将一个对象的值复制到另一个对象。而在Java中,它会声明A引用B指向的对象。由于现在JVM已经丢失了对B的引用并且它不再可达,它就成为GC的合格候选者。
答案 2 :(得分:2)
在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中一样。
答案 3 :(得分:2)
java中的普通对象创建
SomeClass obj = new SomeClass();
如上所示,当您使用java中的new
关键字创建新对象时,JVM会在堆区域中分配所需的内存,并将该内存区域分配给给定的引用变量,obj
在我们的示例中。因此,在您的情况下,它为2个对象分配内存,并为相应的引用变量分配引用。
当你做的时候
A = B;
我们正在指示JVM分配内存引用,由B引用变量A.所以,现在A和B都指向相同的内存区域。在执行赋值语句之前,其他内存区域(实际上由A指向)未被任何引用指向,因此有资格进行垃圾回收