为什么autoboxed整数和.getClass()值== – 相等,不仅.equals() – 相等?
也许我一直在Java上工作太久而没有真正理解它的一些基础知识。
我知道==
用于对象引用相等,而.equals()
用于对象值相等。
-
比较
Integers
:Integer x = 1, y = 1; System.out.println(x == y); // true
为什么? 由于使用了对象引用相等,因此它们应该是假的,因为它们都是不同的对象。
-
比较
getClass()
返回值:String s1 = "a", s2 = "b"; System.out.println(s1.getClass() == s2.getClass()); // true
为什么? 再次如上所述,使用对象引用。 两者都使用
getClass
将返回单独的Class对象。
我是否遗漏了一些东西,或者我的思绪是否厌倦了Java编码?
整数对象
Integer x = 1, y = 1; System.out.println(x==y); // true, why?
这是因为对于byte
范围(-128到+127)中的值,java使用缓存的Integer对象,存储在Integer的内部类IntegerCache中 。 每次创建一个介于-128和+127之间的Integer对象时,将返回相同的对象 (而不是创建新对象)。
相反,对于byte
范围之外的值,比较结果为false
:
Integer x = 999, y = 999; System.out.println(x==y); // false
类对象
String s1 = "a", s2 = "b"; System.out.println(s1.getClass() == s2.getClass()); // true. Why?
这是正确的,因为两个对象的类都是String
,每个JVM只有一个每个类对象的副本(它就像一个单例)。 从每个String的getClass()
返回的类对象是相同的类对象( String.class
)。
一个很好的问题。 由于Integer
是不可变的,因此Java实现不保证您将为每个Integer获取唯一的对象。 Java使用一个Integer
对象池来获取小值-128到+127,因此a
和b
都引用相同的底层1
对象。
至于b,两个字符串都是相同String
类的实例。 getClass()
为每个返回相同的Class
对象。
如果您还不知道,这与自动装箱/拆箱概念有关。 因此,当您比较Integer
对象时,可以想象编译器在比较它们时会自动添加intValue()
– 因此它基本上变成原始值比较而不是对象相等。
关于String,那是因为它比较了类/类型,它们在JVM中始终是一个(因此也是相同的)。
您对==
和equals()
理解是正确的。 在第一种情况下,它是因为缓存。 在第二种情况下,对象的类总是相同的,它不依赖于实例。 如果确实如此,那将是对内存的巨大浪费。