【问题标题】:Do two objects of a class refer to the same memory location?一个类的两个对象是否引用相同的内存位置?
【发布时间】:2015-09-14 21:05:54
【问题描述】:

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

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

【问题讨论】:

  • 没有。他们不会。 String 池仅适用于 String 文字; new String("a") != new String("a")...
  • @BoristheSpider “字符串池仅适用于字符串文字” 并手动添加字符串。 (只是为了完成那句话):)
  • 根据定义,两个对象始终具有不同的内存位置。

标签: java memory garbage


【解决方案1】:

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

答案是

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

【讨论】:

  • (The range of values cached by the JVM is not specified explicitly as far as my knowledge goes) 正确,唯一指定的是 -128 和 127 之间的范围 必须 被缓存,但除此之外它取决于实现。如此之多,以至于在 Oracle VM(可能还有其他 VM)中,您可以通过参数 -XX:AutoBoxCacheMax 更改此范围
  • @biziclop 谢谢。使声明更加明确。另外,我不知道-XX:AutoBoxCacheMax 标志。学到了一些新东西:)
【解决方案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 合并这两个对象,第一个对象的同步将不得不等待第二个对象的同步。

【讨论】:

  • 在使用缓存的情况下,根本没有两个对象,只有一个,所以问题的条款不适用。
  • +1 用于指出同步。这种设计方式意味着在 Java 中没有任何对象是不可变的。因此,任何依赖于对象不变性的对象池都是易受攻击的,除非您绝对承诺不同步它们。
【解决方案3】:

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

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-06-30
    • 2014-09-07
    • 1970-01-01
    • 2014-06-28
    • 1970-01-01
    • 1970-01-01
    • 2014-11-29
    • 1970-01-01
    相关资源
    最近更新 更多