我和我的老师交谈时,她提到一个对象变量(指的是一个对象实例)并不包含对象本身,而是其在内存中的地址。
我听说在Java中,对象实例确实包含对内存中对象的引用。我错了吗?引用和包含内存地址是相同的东西,还是其他什么?
我和我的老师交谈时,她提到一个对象变量(指的是一个对象实例)并不包含对象本身,而是其在内存中的地址。
我听说在Java中,对象实例确实包含对内存中对象的引用。我错了吗?引用和包含内存地址是相同的东西,还是其他什么?
一个对象变量并不等同于一个对象实例。你需要明确区分变量、它们的值和对象之间的差别,这非常重要。
例如:
String x = "hello";
< p >变量< em >x < /em >。它就像一张纸,上面可以写上< em >值< /em >。< /p >
< p >变量的< em >值< /em >是一个引用——一些数据,VM可以使用它来获取字符串对象本身。它不一定是一个地址,只是“获取对象数据的一种方式”。(想了解更多信息,请阅读Eric Lippert的博客文章“引用并非地址”——这是针对C#而非Java,但原理相同)。< /p >
< p >< em >对象本身是一个独立的实体。< /p >
< p >举个现实中的例子,想象我有一张写着我的家庭地址的纸。这里显然有三件事:< /p >
当你考虑参数传递和变量赋值等问题时,这变得很重要。例如:< /p>
House x = new House("Jon");
House y = x;
这里有两个变量,x
和 y
,就像两张纸一样。我们建造了一座房子,并在 x
上写下了到达它的指示。然后我们将写在 x
上的值复制到 y
上。请注意,它们仍然是完全独立的纸张,但它们目前具有相同的值。只有一个对象 - 我们只建造了一座房子 - 但现在两张纸上都写有同样的指示。
如果一个人按照纸张 x
上的指示把门漆成红色,那么另一个人按照纸张 y
上的指示他们会找到一座带有红色前门的房子。
另一方面,如果一个人涂掉了纸张 x
上的指示,那并不会对纸张 y
上的指示产生影响。
好的,不完全是内存地址,但在JVM中可以将其翻译成类似的东西。
问题在于Foo foo = new Foo()
只是对Foo
的引用,而不是整个Foo
结构。
引用是指对象在内存中的地址。这个“内存”实际上更像是一块空间,用于创建与执行无关的东西(调用帧等实际上用于执行)。
是的,有点类似。当你使用new运算符分配一个对象时,它被分配在堆上,并返回对该位置的引用。当你声明一个变量如:Object foo时,foo变量并没有被分配在堆上。变量不是对象,而是对象的引用。它们被创建在栈上作为局部变量或者在对象中作为实例变量。foo可以引用堆上的某个东西。它非常像C语言中的指针,但主要区别在于它不仅仅是一个内存地址(原因有点复杂,但就所有目的而言,你可以把引用看作指针)。Java与C语言最大的区别在于你不能操作指针。你不能确定它的值,也不能对它进行任何数学运算。这些都是为了你自己和程序的安全考虑。你可以通过将其赋值给另一个引用或null来更改foo指向的内容。
Car c = new Car();
在上面的例子中,c是一个引用变量,它包含由new运算符生成的引用ID,该ID以哈希码形式包含对象的位置,因为出于安全目的。在Java中,引用ID类似于C ++中的指向指针,因为它是一个内存位置,其中包含对象实际存在的内存位置。引用ID始终在堆栈中获得内存,而对象始终在堆中获得内存。
请考虑
A a1 = new A();
这里A是一个类,a1是引用变量,指向堆内存中的某个位置。堆内存中的区域(也称为对象)包含属性和方法(方法用于消息传递,存储在方法表中)。
如果从创建对象的类中调用对象,则不需要使用点符号。否则,我们必须使用点符号。
例如:
class A
{
static int age;
static int email;
mehtod1()
{
}
mehtod2()
{
}
...
...
...
A a1 = new A();
A a2 = new A();
A a3 = a1;
}
class B
{
some attributes;
...
...
...
a1.method1();// will pass method 1 to object1
}
在Java中,对对象的调用几乎就像处理数学问题(例如在两个变量之间使用表达式2+4=6)和英语一样。
就像“机器人向左移动5个单位”。
robot.movesleft(5); // robot is object and movesleft is method or function which tells robot what to do can be anything like eat(banana), sleep(50) blah blah
将“+”替换为“点”
Objects are purely handled at JVM and Computer doesnot know what objects are(hardware only knows subroutines(sub-functions) and attributes)
如果我哪里错了,请纠正我
实例不持有内存地址,而是持有一些只有JVM能够理解的地址。例如下面的示例中,h1
持有 "com.mmm.examples.Hippo@3d4eac69"
,其中 "packageName.ClassName@someaddress"
示例:
Hippo h1 = new Hippo();
System.out.println(h1);
System.out.println("h1.size = " + h1.size);//
com.mmm.examples.Hippo@3d4eac69