zoukankan      html  css  js  c++  java
  • 深入探究Java中equals()和==的区别是什么

    “判断两个事物是否相等”,是编程中最常见的操作之一,在Java中,判断是否相等有两种方法,一种是使用“==”判断符,另一种是使用“equals()”方法,你是否曾因混用二者导致不可思议的bug?本篇文章将带你深入二者背后的判断原理。

    相等判断符"=="

    "=="相等判断符用于比较基本数据类型和引用类型数据。 当比较基本数据类型的时候比较的是数值,当比较引用类型数据时比较的是引用(指针)。

    "=="判断基本类型数据

    基本数据类型指的是Java中的八大数据类型:byte,short,int,long,float,double,char,boolean

    这八大基本数据类型有个共同的特点是它们在内存中是有具体值的, 比如说一个int类型的数据"2",它在8位数据总线的机器上(假设的是8位)保存形式为 0000 0010。

    当使用"=="比较两个基本数据类型的时候, 就是比较它们各自在内存中的值。

    "=="判断引用类型数据

    引用数据类型在字面上也是很好理解的, 它就是一个引用, 指向堆内存中一个具体的对象。

    比如说Student stu = new Student(); 这里的 stu 就是一个引用,它指向的是当前 new 出来的 Student 对象. 当我们想要操作这个 Student 对象时, 只需要操作引用即可, 比如说int age = stu.getAge();

    所以用"=="判断两个引用数据类型是否相等的时候,实际上是在判断两个引用是否指向同一个对象

    看下面的示例:

    public static void main(String[] args) {
        String s1 = "hello";	//s1指向字符串常量池中的"hello"字符串对象
        String s2 = "hello";	//s2也指向字符串常量池中的"hello"字符串对象
        System.out.println(s1 == s2);   //true
    
        String s3 = new String("hello");   //s3指向的是堆内存中的字符串对象 
        System.out.println(s1 == s3);	//false
    }

    从上面的例子可以看到,由于引用"s1"和"s2"指向的都是常量池中的"hello"字符串,所以返回true。

    而"s3"指向的是新创建字符串对象,因为只要动用了new关键字, 就会在堆内存创建一个新的对象。

    也就是说 s1 和 s3 指向的是不同的字符串对象,所以返回false。

    相等判断方法equals()

    equals()和 == 有着本质的区别,== 可以看作是对“操作系统比较数据手段”的封装,而equals()则是每个对象自带的比较方法,它是Java自定义的比较规则。

    equals()和 == 的本质区别更通俗的说法是:==的比较规则是定死的,就是比较两个数据的值。

    而 equals() 的比较规则是不固定的,可以由用户自己定义。

    看下面的例子:

    public static void main(String[] args) {
        String s1 = "hello";
        String s3 = new String("hello");    
        System.out.println(s1.equals(s3));	//true
    }
    

    回想前面的案例:用 == 比较的时候, 上面 s1 和 s3 比较出的结果为false。而当用 equals() 比较的时候,得出的结果为 true。

    想知道原因我们还得看源码,下面是 String 类中的 equals() 方法的源码。

    public boolean equals(Object anObject) {
        if (this == anObject) {	//先比较两个字符串的引用是否相等(是否指向同一个对象), 是直接返回true
            return true;
        }
        if (anObject instanceof String) {	//两个引用不等还会继续比较
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;	//字符串类是用字符数组实现的, 先要拿到两个字符串的字符数组
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {	//然后对两个数组逐个字符地进行比较
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }
    

    从上面的源码可以看到, 当调用 String 类型数据的 equals() 方法时,首先会判断两个字符串的引用是否相等,也就是说两个字符串引用是否指向同一个对象,是则返回true。

    如果不是指向同一个对象,则把两个字符串中的字符挨个进行比较。由于 s1 和 s3 字符串都是 "hello",是可以匹配成功的,所以最终返回 true。

    思考:为什么要设计equals()方法?

    下篇博客为大家解释为什么要设计equals()方法

     
  • 相关阅读:
    Java的Integer与int互转
    浅析Java中的final关键字
    zookeeper leader作用
    闭包的潜在用处
    Keystone controller.py & routers.py代码解析
    zookeeper 同步
    elk 分布式数据同步
    mget 同时获取
    Elasticsearch 单模式下API的增删改查操作
    安装 插件,查看插件
  • 原文地址:https://www.cnblogs.com/changyuyao/p/13093239.html
Copyright © 2011-2022 走看看