类的两个对象是否指向相同的内存位置?

时间:2015-06-28 09:29:56

标签: java memory garbage

我开始学习一些Java,我已经阅读了很多关于如何通过JVM分配内存以及因此如何使用垃圾收集器释放内存的内容。

我无法找到的一件事是,如果我创建了两个完全相同的新对象,它们会引用内存中的相同位置吗?与String Pool的工作方式类似。

3 个答案:

答案 0 :(得分:7)

  

我无法找到的一件事是,如果我创建了两个完全相同的新对象,它们会引用内存中的相同位置吗?与字符串池的工作方式类似

答案是

  1. 如果使用new关键字创建两个对象,它们将永远不会指向相同的内存位置。
  2. 这也适用于String个对象。如果使用String创建两个new个对象, 对这些对象的两个引用将指向两个不同的对象 记忆位置。
  3. String文字是一个特例。 String文字存储在String文字池中。因此,对String文字的两个String引用将始终指向相同的内存位置。
  4. Java中还有其他特殊情况,例如Integer类。例如Integer a = 100; Integer b = 100; System.out.println(a==b);这打印为true,因为JVM缓存了-128到127之间的Integer值。 (所有JVM实现都缓存了-128到127 之间的值。单个JVM实现可以缓存超出此范围的值)

答案 1 :(得分:2)

如果使用new运算符创建新对象,则保证它是与以前存在的任何其他对象不同的新对象。但是,当您以间接方式创建对象时(例如,使用工厂方法),之前存在的对象可能会被重用。一个很好的例子是Integer.valueOf(int)方法,它缓存小数字并返回相同的实例:

Integer a = Integer.valueOf(10);
Integer b = Integer.valueOf(10);
// a and b is the same object
Integer c = new Integer(10);
Integer d = new Integer(10);
// c and d are two distinct objects

请注意,即使JVM可以确定两个新对象基本相同,它也不能将它们合并到单个对象,因为它会违反语言规范并可能在以后破坏您的程序。例如,您可以决定稍后同步这两个对象。根据规范,这些同步不应该干扰,但如果JVM合并这两个对象,第一个上的同步将不得不等待第二个上的同步。

答案 2 :(得分:-1)

不,它们不是同一个对象。您可以使用==操作验证这一点,该操作检查两个引用是否引用同一对象。

String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);

这将打印false,这就是您通常永远不想将String(或实际上任何对象)与==进行比较的确切原因(参考this post )。检查(内容)平等的正确方法是equals(Object that)