在Java中,对象变量是否包含对象的地址?

时间:2012-01-19 21:30:43

标签: java

我正在和老师谈话,她提到一个对象变量(她的意思是一个对象的实例)不包含对象本身,而是包含内存中的地址。

我听说在Java中,对象的实例确实包含对内存中对象的引用。我错了吗?引用与包含内存中的地址或其他内容相同吗?

7 个答案:

答案 0 :(得分:12)

对象变量不是与对象的实例相同。 非常重要,您可以区分变量,它们的值和对象。

例如:

String x = "hello";

变量x。它就像一张纸,上面写着

变量的是一个引用 - VM可用于获取字符串对象本身的一些数据。它不一定是一个地址 - 它只是“获取对象数据的一种方式”。 (有关这方面的更多信息,请阅读Eric Lippert的博客文章"References are not addresses" - 这是关于C#而不是Java,但它的原理是相同的。)

对象本身就是一个独立的实体。

要使用真实世界的例子,想象一下我的家庭住址上写着一张纸。这里显然有三件事:

  • 这张纸(就像一个变量)。这张纸本身不是我的家庭住址,也不是房子。它只是可以存储价值的东西。
  • 我家的地址不是纸,也不是房子。这只是让某人 到我家的价值。
  • 我的房子既不是一张纸,也不是一个地址。这是一个对象。

当您考虑参数传递和变量赋值之类的事情时,这变得很重要。例如:

House x = new House("Jon");
House y = x;

这里我们有两个变量xy,就像两张纸一样。我们建造了一所房子,并在x上写下了它的指示。然后,我们将<{1}}上写的值复制x。请注意,它们仍然是完全独立的纸张 - 但它们目前具有相同的值。只有一个对象 - 我们只建了一个房子 - 但现在两张纸的方向相同。

如果一个人按照纸张上的说明y并将前门涂成红色,那么第二个人按照纸张x上的指示,他们会找到一个带有纸张的房子红色的前门。

另一方面,如果一个人在纸上y上抄写了指示,那就不会影响纸张x上的指示。

答案 1 :(得分:5)

嗯,不完全是内存地址,而是JVM中可以翻译的内容,是的。

事情Foo foo = new Foo()仅是Foo的引用,而不是Foo的整个结构。

答案 2 :(得分:1)

引用与“内存中”对象的地址相同。 “内存”实际上更像是一块空间,用于创建与执行无关的内容(调用框架等是实际用于执行的内容)

答案 3 :(得分:0)

是的。使用new运算符分配对象时。它在堆上分配,并返回对该位置的引用。当您声明一个变量时:Object foo。 foo变量并没有在堆上分配。变量不是对象,而是对对象的引用。它们在堆栈上为局部变量创建,或者在对象中创建,如果它是实例变量。 foo可以引用堆上的东西。它非常像来自C的指针,但主要区别在于它不仅仅是一个内存地址(为什么有点复杂的细节,并且为了所有密集的目的,你可以将引用视为一个指针)。与C相比,你在Java中的最大区别是你无法操纵指针。你无法确定它的价值,也不能对它进行任何数学计算。这些主要是为了您自己和程序的安全。您可以通过将foo指向另一个引用来更改foo指向的内容,或者将其指向null,就像指向任何内容一样。

答案 4 :(得分:0)

考虑

 A a1 = new A();

这里A是类a1是指向HEAP内存中某处的引用变量,堆内存中的区域(又名对象)保存属性和方法(方法用于消息传递并存储在方法表中)

如果从创建对象的类调用object,则不需要dot约定,否则我们必须去点

 class A
 {
   static int age;
   static int email;

  mehtod1()
  {
   }
  mehtod2()
  {
  }

  ...
 ...
 ...

 A a1 = new A();
 A a2 = new A();
A a3 = a1;
 }

现在a1和a3是同一个,每个a1,a2,a3只能访问一个静态全局属性的副本(不是每个对象一个)年龄和电子邮件;

现在

 class B
 {

 some attributes;
...
 ...
 ...

 a1.method1();// will pass method 1 to object1

}

IN对对象的java调用几乎就像使用数学一样(在两个变量2 + 4 = 6之间表达)和英语

像ROBOT MOVES LEFT BY 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)

如果我错了,请纠正我

答案 5 :(得分:0)

Car c = new car();

在上面的示例中,c是一个引用变量,它包含由new运算符生成的引用ID,该运算符由于安全目的而包含哈希码形式中对象的位置。 java中的引用ID就像是指向C ++中指针的指针,因为它是一个内存位置,它包含实际存在的对象的内存位置。引用ID始终在Stack中获取内存,而Object始终在Heap中获取内存。

答案 6 :(得分:-1)

实例不保存内存地址,而是保留一些只有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