前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >equals 和 == 到底有什么区别?

equals 和 == 到底有什么区别?

作者头像
一份执着✘
发布2018-06-04 16:54:45
6310
发布2018-06-04 16:54:45
举报
文章被收录于专栏:赵俊的Java专栏赵俊的Java专栏

Java 中的 equals== 对于不同的数据类型有不同的表现,话不多少,看演示。

对于基本数据类型

对于基本数据类型来说,只能用 ==,所以毫无疑问,这里是用来判断两个基本数据类型的值是否一致。

对于基本数据类型包装类

先来看看这种创建对象的方式:

代码语言:javascript
复制
public class Demo {
    public static void main(String[] args) {
        Integer i1 = new Integer(100);
        Integer i2 = new Integer(100);
        System.out.println(i1 == i2);
        System.out.println(i1.equals(i2));
    }
}

运行结果:

代码语言:javascript
复制
false
true

这里可能会有人疑问,== 不是判断两者是否相等么,那为什么结果为 false 呢?

因为这里的 Integer 是一个对象,也就是引用数据类型,里面存放的是对象在堆内存中的引用值,所以这里的 == 只是判断两者的引用值是否相同,两者创建了两个对象,在堆内存中分别是不同的引用,由而引用值也不同,才会返回 false

那么我们再看一下简化版的 Integer 的创建方式:

代码语言:javascript
复制
package other;

public class Demo {
    public static void main(String[] args) {
    
        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1 == i2);
        System.out.println(i1.equals(i2));
        
        Integer i3 = 1000;
        Integer i4 = 1000;
        System.out.println(i3 == i4);
        System.out.println(i3.equals(i4));
    }
}

运行结果:

代码语言:javascript
复制
true
true
false
true

equals 毫无疑问是判断值是否相同,所以结果为 true,但是为什么第一个 == 又为 true 了呢,而第二个 == 还是 false。

因为在 Java 5 中,为 Integer 的操作引入了一个新的特性,用来节省内存和提高性能。整型对象在内部实现中通过使用相同的对象引用实现了缓存和重用。但适用范围只有 -128+127 也就是说当自动装箱时,不会再分配内存空间,而是使用缓存中已存在的对象。

最大值 127 可以通过 JVM 的启动参数 -XX:AutoBoxCacheMax=size 修改

这种缓存行为不仅适用于 Integer 对象。我们针对所有整数类型的类都有类似的缓存机制。ByteShortLongCharacter 都支持缓存。

其中 ByteShortLong 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行。

对于基本数据类型包装类而言,不论是使用哪种方式创建的,判断两者的值是否相同,务必要使用 equals ,而不要使用 ==

对于自定义数据类型

首先有 Person 类:

代码语言:javascript
复制
public class Person {
    private int id;
    private String name;
    
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    
}

然后示例:

代码语言:javascript
复制
public class Demo {
    public static void main(String[] args) {
        Person p1 = new Person();
        p1.setId(1);
        p1.setName("张三");
        
        Person p2 = new Person();
        p2.setId(1);
        p2.setName("张三");
        
        System.out.println(p1 == p2);
        System.out.println(p1.equals(p2));
    }
}

这里使用 == 的结果为 true 很容易理解,毕竟两个对象的引用不同,但是 equals 不是判断值是否相同么,我的两个idname 都是一样的,为什么这里还会返回 false 呢?

Person 中我们没有写 equals 方法,根据 Java 继承的特点,Person 类继承的是 Object,所以使用的是 Object 的 equals 方法,那我们来看看 Object 的 equals 方法是怎么写的。

![image_1bo22o7qv1e801ivjhqftge18d1m.png-24.9kB][1]

原来这里的 equals 方法里用的也是 ==,那么刚才我们用基本数据类型包装类时,为什么能判断呢,同样,我们找到 Integer 的 equals 方法。

![image_1bo22v5je88n1d611g3la3e1a1m13.png-33kB][2] ![image_1bo2315q517g21glb14ni11c9hdp2n.png-18.8kB][3]

可以看 Integer 的 equals 方法,会先判断该对象是否是一个 Integer 类的一个实例,如果不是则直接返回 false,是的话就比较他们的 value 值是否相等。

所以在我们自定义数据类型时,比较两个对象是否相同,一定要重写 equals 方法。

代码语言:javascript
复制
@Override
public boolean equals(Object obj) {
    
    if (obj instanceof Person) {
        
        Person p = (Person)obj;
        
        if (this.id == p.id && this.name == p.name) {
            return true;
        }
    }
    return false;
}

重写 equals 方法后的运行结果:

代码语言:javascript
复制
false
true

对于 String

String 也有两种创建方式,一种是 String str = new String("java");,另一种是 String str = "java"

Java 为 String 类型提供了缓冲机制,当使用第二种双引号的形式创建对象时,Java 会先去字符串缓冲池中寻找内容相同的字符串,如果存在就直接拿来应用,如果不存在就创建一个新的字符串放到缓冲池中。对于第一种 new 对象的形式而言,每次都会创建一个新的对象,不会访问字符串缓冲池。

既然如此,对于 String 的 equals== 你也自然应该明白是什么结果了。

一般情况下,建议使用 String s = "abc" 方式,因为该方式采用的是字符串缓冲池机制,效率更高。

结论

在引用类型中,”==” 是比较两个引用是否指向堆内存里的同一个地址(同一个对象),而 equals 是一个普通的方法,该方法返回的结果依赖于自身的实现。

对于引用类型而言,判断两者是否相同要用 equals 方法,而不是 ==。当然对于自定义数据类型,记得要重写 equals 方法,不然效果就等同于 == 了。 [1]: https://cdn.jun6.net/image_1bo22o7qv1e801ivjhqftge18d1m.png [2]: https://cdn.jun6.net/image_1bo22v5je88n1d611g3la3e1a1m13.png [3]: https://cdn.jun6.net/image_1bo2315q517g21glb14ni11c9hdp2n.png

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-08-212,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 对于基本数据类型
  • 对于基本数据类型包装类
  • 对于自定义数据类型
  • 对于 String
  • 结论
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档