当我们创建Java基本变量或Java对象时,如何在内存中表示/构造它?
int A;
//是对创建的整数类型的引用吗?
// //是保存在内存中分配的整数类型所需的内存空间吗?
A = 3;
//现在是否分配了保存整数类型所需的存储空间?然后引用该空间。
int B = 2;
A = B;
//是A将存储位置引用为B吗?并且A引用的旧内存位置是垃圾回收?
//如果是,则修改A也将导致修改B,对吗?
//如果否,则按值传递已完成。
//是否修改了A引用的内存位置,或者已经创建了一个能够保存int的新内存位置,并填充了B引用的值,然后又由A引用了?
如果A是类对象,是否也类似?
答案 0 :(得分:0)
在进行A=B
操作时,为A
引用的整数分配的内存才有资格使用GC。
现在,当您对一个变量进行修改时,您将引用与该值相对应的其他内存位置,并且由于它位于堆栈中,因此不会影响另一个。
例如,执行A = 6
不会影响B
的值; B仍然保持值为2
。
最后,与A是类对象的情况不同,因为对象进入了堆内存。
看看这篇Wiki的文章,我发现它很有解释性。
答案 1 :(得分:0)
Java中的原语进入栈,因此它们存储在变量的位置。请记住,尽管字符串被认为是不可变的,但它不是原始的,而是类。
因此,变量A和B都保留值2,但是不共享该值。附带说明一下,Java对int变量做了一些有趣的事情。如果它们足够低,它们实际上甚至不存储在堆栈上,而是在内存中引用静态分配(由预编译器处理)。
现在,如果要分配类实例,则该零件。然后情况发生了一些变化。如果将实例分配给A,则可以在堆栈上分配对A的引用,然后在堆上分配它。然后将A分配给B时,两者都将引用堆中的同一实例。直到两个引用都超出范围,该实例才会被垃圾回收。
如果您重新分配A或B,它们将不再指向堆中的同一实例。
答案 2 :(得分:0)
每种类型的数据类型都有不同数量的数据分配用于存储该数据类型,这就是为什么我们限制了大小(例如,整数可以为(-2,147,483,648到2,147,483,647,a最多32位)。其他数据类型(例如float和double)具有不同的值,其中float是32位浮点值,而double是64位double精确浮点值。
关于您是否更改B的问题,是否会更改A,简短的回答是“否”。当您定义一个等于B的变量A时,您正在做的就是将A的值更改为等于B。另一个示例,如果您具有下面的代码(任何OO语言),您正在做什么在内存中创建一个零位值(分配的空间为32位),并且您正在创建第二个 new 变量,其变量值为 a ,该值为零。 编辑:第二个变量完全独立于第一个变量。
int a = 0;
int b = a;
在某种情况下,可以通过更改原始值来修改一个变量,这称为指针。指针是一种特殊的小工具,用于保存有关数据在存储器中存储位置的信息,否则称为存储器地址。看看下面的代码。
Person* person = new Person();
int* age = person.age;
在这里,我声明了两个指针,一个是对要实例化的对象的引用,另一个是对该对象中字段的链接。指针存储给定数据在存储器中的存储位置的信息(存储器地址)。由此,无论何时使用指针,它都充当指向该内存地址的指针,供我们访问。因此,它实际上不是变量,而是充当“目录”中的列表,您可以在其中使用它来查找数据。因为它不直接存储任何数据,而只是对存储数据的引用,所以当直接使用 person.age 更改人的年龄时,它也会在内存中更新其数据,但是地址保持不变,并将反映在指针上。
关于垃圾收集问题,在Java或C#这样的语言中,仅当不再有对该信息的引用时,才对数据进行垃圾收集。但是,在C ++之类的语言中,不会自动进行垃圾回收,因此必须删除使用 delete 关键字创建的指针。
无论如何,希望这会有所帮助!
答案 3 :(得分:0)
对于基本类型:
int i = 10;
int j = i;
i = 11
在Java中,为i和j的值分配了8字节的内存(i的4字节和j的4字节)。 i的值传递给j,现在j和i具有相同的值,但内存地址不同。 现在,i的值更改为11,这意味着对于相同的内存地址,i的值从10更改为11,但是j的值位于不同的存储位置,因此仍为10。
对于对象,值(或引用)本身就是一个地址(或堆地址),因此,如果其中一个更改,它也将对其他对象反映。例如在对象中:-
Person p1 = new Person();
Person p2 = p1;
因此p1进行更改或p2进行更改将同时更改两者。无论是Java,Python还是Javascript都是相同的。在原始情况下,它是实际值,在对象情况下,它是实际对象的地址-这就是窍门。