为什么autoboxed整数和.getClass()值== – 相等,不仅.equals() – 相等?

也许我一直在Java上工作太久而没有真正理解它的一些基础知识。
我知道==用于对象引用相等,而.equals()用于对象值相等。

  1. 比较Integers

     Integer x = 1, y = 1; System.out.println(x == y); // true 

    为什么? 由于使用了对象引用相等,因此它们应该是假的,因为它们都是不同的对象。

  2. 比较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,因此ab都引用相同的底层1对象。

至于b,两个字符串都是相同String类的实例。 getClass()为每个返回相同的Class对象。

如果您还不知道,这与自动装箱/拆箱概念有关。 因此,当您比较Integer对象时,可以想象编译器在比较它们时会自动添加intValue() – 因此它基本上变成原始值比较而不是对象相等。

关于String,那是因为它比较了类/类型,它们在JVM中始终是一个(因此也是相同的)。

您对==equals()理解是正确的。 在第一种情况下,它是因为缓存。 在第二种情况下,对象的类总是相同的,它不依赖于实例。 如果确实如此,那将是对内存的巨大浪费。