如果我们声明一个对象并将其分配给相同 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;

你让 AB 指向 FirstClass(2) 并且 "nothing" 指向 FirstClass(1)... 因为有 "nothing" 指向为此,FirstClass(1) 有资格进行 GC。

Java中的变量有两种。它们要么是原始类型(例如 intboolean),要么是 Object 类型。原始值总是在赋值时被复制,但对象变量就像 C++ 中的指针一样。如果您将一个 Object 变量分配给另一个,那么您只是更改它指向的内存位置,而不是创建目标的新 "copied" 实例。

在Java中,AB实际上是指针。但在您的 C++ 代码中,它们不是。这是唯一的区别。

如果将 C++ AB 更改为指针,您会发现这两段代码现在是等价的:

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 指向)没有被任何引用指向,因此符合垃圾收集条件