• ==的分析

    1.对于基本数据类型,比较的是他们的具体内容是不是一样,跟他们的内存地址无关。举个栗子:

    public class Test{
    
    	public static void main(String[] args) {
    int i = 10;
    double j = 10.0;
    float m = 10.0f;
    char k = 10;
    boolean b = true; System.out.println(i == j);
    System.out.println(i == m);
    System.out.println(m == k);
    System.out.println("*******************");
    //System.out.println(i == b); 很明显,布尔型不能和其他基本数据类型比较,编译报错.
    System.out.println(System.identityHashCode(i));
    System.out.println(System.identityHashCode(j));
    System.out.println(System.identityHashCode(m));
    System.out.println(System.identityHashCode(k));
    System.out.println(System.identityHashCode(b));
    }
    }

    输出结果:

    true
    true
    true
    *******************
    366712642
    1829164700
    2018699554
    1311053135
    118352462

    分析:

    ​ ①根据比较的结果和内存地址来看,内容一样,内存地址不一样,但是返回的结果都是true,说明比较的 时候只看变量中存储的内容是否相同,而跟内存地址无关。

    ​ ②==比较的两边数据需要能强制转换成同一类型,比如intdouble的比较,会强制转换到double

    ​ ③布尔类型不能和int,float,double,char等基本数据类型做比较,编译时就报错。

    2.对于引用数据类型的比较:

    public class Test{
    
    	public static void main(String[] args) {
    Test t1 = new Test();
    Test t2 = new Test();
    String name1 = "琼宝";
    String name2 = "琼宝"; System.out.println(name1 == name2); // true
    System.out.println(System.identityHashCode(name1)); //366712642
    System.out.println(System.identityHashCode(name2)); //366712642 System.out.println(t1 == t2); //false
    System.out.println(System.identityHashCode(t1)); //366712642
    System.out.println(System.identityHashCode(t2)); //1829164700
    System.out.println(System.identityHashCode(new Test())); //2018699554
    System.out.println(System.identityHashCode(new Test())); //1311053135
    System.out.println(new Test() == new Test());
    }
    }

    输出结果:

    true
    366712642
    366712642
    false
    366712642
    1829164700
    2018699554
    1311053135
    false

    分析:

    ​ ①对于引用数据类型,此时涉及到两块内存的问题, 而且比较的也是内存地址是否相同,比如执行语句

    Test t1 = new Test() Test t2 = new Test()时,会开辟两块内存,一块用于储存t1 t2 ,一 块用于储存两个 new Test()。而很明显的是,t1和t2的内存地址不一样,就连两个new Test()的地 址都不一样,所以此时用==来比较的时候,结果必然是false.(补充:t1和t2中存储的其实是new Test() 对象使用的内存的首地址。)

    ​ ②对于String类型来说,内容相同的时候,其内存地址也相同,比较的时候看的也是地址。

    ​ ②如果要比较对象中存储的内容是否相同(不是比较地址),那么==就无法实现,此时需要equals.


  • equals的分析

    1.先看一个equals比较的栗子:

    public class TestEquals {
    public static void main(String[] args) { TestEquals t1 = new TestEquals();
    TestEquals t2 = new TestEquals();
    System.out.println(t1.equals(t2)); //false String s1 = new String();
    String s2 = new String(); System.out.println(System.identityHashCode(s1));
    System.out.println(System.identityHashCode(s2));
    System.out.println(System.identityHashCode(new String()));
    System.out.println(System.identityHashCode(new String()));
    System.out.println(s1.equals(s2)); // true
    }
    } 输出结果:
    false
    366712642
    1829164700
    2018699554
    1311053135
    true

    2.分析:

    ​ ①t1和t2的比较是false,而s1和s2的比较是true,这里就涉及到了equals方法的重写问题,先看 Object类 中equals的源码:

    public boolean equals(Object obj) {
    return (this == obj);
    }

    ​ ② 对于s1.equals(s2) ,this就是s1,obj是s2,而源码中的比较用的是==,很明显是引用数据类型的比 较,看的是s1和s2的内存地址,上面的分析已经知道他们的地址不一样,所以结果自然就是false.

    ​ ③而s1和s2的比较结果是true,这是因为在String类中,equals方法被重写了,看源码:

    public boolean equals(Object anObject) {
    if (this == anObject) {
    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;
    }

    ​ ④通过和object中equals源码的对比可以看出,String中的equals方法比较的不再是对象的地址,而是看 两个对象内容,或者两个对象的属性是否都一样。

    ​ ⑤像String,Date,File…等类都对equals方法进行了重写。


  • 总结

    1.==用于比较基本数据类型时,比较的是内容是否相等,比较引用数据类型时,看的是内存地址是否相等。

    2.equals只能比较引用数据类型(对象),没被重写之前,使用==来比较内存地址,重写后比较的是对象的具 体内容和属性是否一致。

    3.创作不易。感谢支持,欢迎转载转发,但请注明出处。

    4.如对你有帮助,老板大气,感谢打赏一杯熬夜咖啡。

    5 .QQ 321662487

==和equals的深度分析的更多相关文章

  1. java集合框架(1) hashMap 简单使用以及深度分析(转)

    java.util 类 HashMap<K,V>java.lang.Object  java.util.AbstractMap<K,V>      java.util.Hash ...

  2. const与readonly深度分析(.NET)

    前言 很多.NET的初学者对const和readonly的使用很模糊,本文就const和readonly做一下深度分析,包括: 1. const数据类型的优势 2. const数据类型的劣势 3. r ...

  3. 转:[gevent源码分析] 深度分析gevent运行流程

    [gevent源码分析] 深度分析gevent运行流程 http://blog.csdn.net/yueguanghaidao/article/details/24281751 一直对gevent运行 ...

  4. 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)

    写在前面: Java SE5 提供了一种新的类型 Java的枚举类型,关键字 enum 可以将一组具名的值的有限集合创建为一种新的类型,而这些具名的值可以作为常规的程序组件使用,这是一种非常有用的功能 ...

  5. AndroidService 深度分析(2)

    AndroidService 深度分析(2) 上一篇文章我们Service的生命周期进行了測试及总结. 这篇文章我们介绍下绑定执行的Service的实现. 绑定执行的Service可能是仅为本应用提供 ...

  6. 深度分析如何在Hadoop中控制Map的数量

    深度分析如何在Hadoop中控制Map的数量 guibin.beijing@gmail.com 很多文档中描述,Mapper的数量在默认情况下不可直接控制干预,因为Mapper的数量由输入的大小和个数 ...

  7. MapReduce深度分析(二)

    MapReduce深度分析(二) 五.JobTracker分析 JobTracker是hadoop的重要的后台守护进程之一,主要的功能是管理任务调度.管理TaskTracker.监控作业执行.运行作业 ...

  8. MapReduce深度分析(一)

    MapReduce深度分析(一) 一.数据流向分析 图为MapReduce数据流向示意图 步骤1.输入文件从HDFS流向到Mapper节点.在一般情况下,存储数据的节点就是Mapper运行的节点,不需 ...

  9. 【JVM】深度分析Java的ClassLoader机制(源码级别)

    原文:深度分析Java的ClassLoader机制(源码级别) 为了更好的理解类的加载机制,我们来深入研究一下ClassLoader和他的loadClass()方法. 源码分析 public abst ...

随机推荐

  1. nyoj 290 动物统计加强版 (字典树 (Trie) PS:map<TLE>)

    动物统计加强版 时间限制:3000 ms  |  内存限制:150000 KB 难度:4   描述 在美丽大兴安岭原始森林中存在数量繁多的物种,在勘察员带来的各种动物资料中有未统计数量的原始动物的名单 ...

  2. pat 1027 Colors in Mars(20 分)

    1027 Colors in Mars(20 分) People in Mars represent the colors in their computers in a similar way as ...

  3. nyoj 244-16进制的简单运算 (scanf("%x%c%x", &a, &b, &c); printf("%o", a ± b))

    244-16进制的简单运算 内存限制:64MB 时间限制:1000ms 特判: No 通过数:12 提交数:13 难度:1 题目描述: 现在给你一个16进制的加减法的表达式,要求用8进制输出表达式的结 ...

  4. 力扣(LeetCode)从不订购的客户-数据库题 个人题解

    SQL架构 某网站包含两个表,Customers 表和 Orders 表.编写一个 SQL 查询,找出所有从不订购任何东西的客户. Customers 表: +----+-------+ | Id | ...

  5. 领扣(LeetCode)移动零 个人题解

    给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序. 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] 说明: 必须在原数组上操作, ...

  6. opencv 5 图像转换(1 边缘检测)

    边缘检测 一般步骤 canny算子 步骤 canny函数 彩色canny #include<opencv2/opencv.hpp> #include<opencv2/highgui/ ...

  7. C++程序的耦合性设计

    声明:本文部分采用和参考<代码里的世界观-通往架构师之路>中内容,可以说是该书中耦合性一章的读后感,感谢该书的作者余叶老师的无私分享. 1.什么是耦合? 耦合其实就是程序之间的相关性. 程 ...

  8. Alibaba Nacos 学习(一):Nacos介绍与安装

    Alibaba Nacos 学习(一):Nacos介绍与安装 Alibaba Nacos 学习(二):Spring Cloud Nacos Config Alibaba Nacos 学习(三):Spr ...

  9. python的time、datetime和calendar

    datetime模块主要是用来表示日期的,就是我们常说的年月日时分秒,calendar模块主要是用来表示年月日,是星期几之类的信息,time模块主要侧重点在时分秒,从功能简单来看,我们可以认为三者是一 ...

  10. ctf线下赛中检测外来IP的shell脚本

    该脚本可用于ctf线下赛中,用来检测攻击IP的接入,及时做出响应. #!/bin/bash #写自己队的ip ipA="172.22.60.230" ipB="172.2 ...