class 的两个对象是否引用相同的内存位置?
Do two objects of a class refer to the same memory location?
我开始学习一些东西 Java 并且我已经阅读了很多关于 JVM 如何分配内存以及如何使用垃圾收集器释放内存的文章。
有一件事我一直无法找到,如果我创建两个完全相同的新对象,它们会指向内存中的相同位置吗?类似于字符串池的工作方式。
不,它们不是同一个对象。您可以使用 ==
操作来验证这一点,该操作检查两个引用是否指向同一个对象。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);
这将打印 false
,这就是为什么您通常不想将 String
s(或者实际上,任何对象)与 ==
进行比较的确切原因(ref this post). The correct way to check for (content) equality is equals(Object that)
.
如果您使用 new
运算符创建新对象,则可以保证它是不同于之前存在的任何其他对象的新对象。但是,当您以间接方式创建对象时(例如,使用工厂方法),之前存在的对象可能会被重用。一个很好的例子是 Integer.valueOf(int)
缓存小数字和 returns 相同实例的方法:
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 合并这两个对象,第一个对象的同步将不得不等待第二个对象的同步。
One thing that I have been unable to find out is if I create two new objects which are exactly the same would they refer to the same location in memory? Similar to how the String Pool works
答案是否:
- 如果使用
new
关键字创建两个对象,它们将永远不会指向相同的内存位置。
- 这也适用于
String
对象。如果您使用 new
创建两个 String
对象,
对这些对象的两个引用将指向两个不同的
内存位置。
String
文字是一种特殊情况。 String
文字存储在 String
文字池中。因此,对 String
文字的两个 String
引用将始终指向相同的内存位置。
- Java 中还有其他特殊情况,例如
Integer
class。例如 Integer a = 100; Integer b = 100; System.out.println(a==b);
打印为真,因为 JVM 缓存了 -128 和 127 之间的 Integer
值。 (所有 JVM 实现都缓存了 -128 和 127 之间的值。缓存超出此范围的值取决于各个 JVM 实现)
我开始学习一些东西 Java 并且我已经阅读了很多关于 JVM 如何分配内存以及如何使用垃圾收集器释放内存的文章。
有一件事我一直无法找到,如果我创建两个完全相同的新对象,它们会指向内存中的相同位置吗?类似于字符串池的工作方式。
不,它们不是同一个对象。您可以使用 ==
操作来验证这一点,该操作检查两个引用是否指向同一个对象。
String s1 = new String("hello");
String s2 = new String("hello");
System.out.println(s1 == s2);
这将打印 false
,这就是为什么您通常不想将 String
s(或者实际上,任何对象)与 ==
进行比较的确切原因(ref this post). The correct way to check for (content) equality is equals(Object that)
.
如果您使用 new
运算符创建新对象,则可以保证它是不同于之前存在的任何其他对象的新对象。但是,当您以间接方式创建对象时(例如,使用工厂方法),之前存在的对象可能会被重用。一个很好的例子是 Integer.valueOf(int)
缓存小数字和 returns 相同实例的方法:
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 合并这两个对象,第一个对象的同步将不得不等待第二个对象的同步。
One thing that I have been unable to find out is if I create two new objects which are exactly the same would they refer to the same location in memory? Similar to how the String Pool works
答案是否:
- 如果使用
new
关键字创建两个对象,它们将永远不会指向相同的内存位置。 - 这也适用于
String
对象。如果您使用new
创建两个String
对象, 对这些对象的两个引用将指向两个不同的 内存位置。 String
文字是一种特殊情况。String
文字存储在String
文字池中。因此,对String
文字的两个String
引用将始终指向相同的内存位置。- Java 中还有其他特殊情况,例如
Integer
class。例如Integer a = 100; Integer b = 100; System.out.println(a==b);
打印为真,因为 JVM 缓存了 -128 和 127 之间的Integer
值。 (所有 JVM 实现都缓存了 -128 和 127 之间的值。缓存超出此范围的值取决于各个 JVM 实现)