zoukankan      html  css  js  c++  java
  • java ==、equals和hashCode的区别和联系

    基础类型

    4种整数类型:int、long、byte、short

    2种浮点数类型:float、double

    1种字符类型:char

    1种布尔类型:boolean

    引用数据类型

    接口

    数组

    1. ==

    1.对于基本类型来说

    ==比较的是值是否相等

    例如:

    
    
    
    
    int a = 1;    
    int b = 1;
    System.out.println(a == b); true
    double a = 1;
    double b = 1;
    System.out.println(a == b); true
    int a = 1;
    int b = 2;
    System.out.println(a == b); false
    double a = 1;
    double b = 2;
    System.out.println(a == b); false


    2.对于引用类型来说

    == 比较的是两者在内存中存放的地址(堆内存地址) 

    获取地址可用:

    System.identityHashCode(Object obj)
    一个对象的identityHashCode能够始终和该对象的内部地址有一个相对应的关系,从这个角度来讲,它可以用于代表对象的引用地址

    以下装箱不懂的可以看java装箱和拆箱内容,看完以后就会懂下面都意思。
    Integer a = 1;
    Integer b = 1;
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 22756955
    System.out.println(a == b); true

    a,b会自动装箱,执行了valueOf函数,它们的值在(-128,128]这个范围内 它们引用到了同一个Integer对象,所以它们肯定是相等的
    Integer a = 200;
    Integer b = 200;
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 1640639994
    System.out.println(a == b); false
    它们的值大于128,所以会执行new Integer(200),也就是说它们会分别创建两个不同的对象,所以它们肯定不等

    Double a = 1.0;
    Double b = 1.0;
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 1640639994
    System.out.println(a == b); false

       对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的

    Boolean a = true;
    Boolean b = true;
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 22756955
    System.out.println(a == b); true

    可以看到返回的都是true,也就是它们执行valueOf返回的都是相同的对象。并没有创建对象,因为在内部已经提前创建好两个对象,因为它只有两种情况,这样也是为了避免重复创建太多的对象
    Integer a = 400;
    int b = 400;
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 1640639994
    System.out.println(a == b); true

    是不是很神奇,地址不一样都相等,其实这是a进行了拆箱
    a进行拆箱返回int,然后就是int和int进行比较,所以返回true

    关于String,这是个特殊的引用类型以下讲解
    String a = "1";
    String b = "1";
    System.out.println(System.identityHashCode(a)); == 22756955
    System.out.println(System.identityHashCode(b)); == 22756955
    System.out.println(a == b); true

    引用同一个 String 对象
    字符串缓冲池

    String s1 = "Monday";
    String s2 = new String("Monday");

    s1 != s2
    s1 equals s2

    原来,程序在运行的时候会创建一个字符串缓冲池当使用 s2 = "Monday" 这样的表达是创建字符串的时候,程序首先会在这个String缓冲池中寻找相同值的对象,在第一个程序中,s1先被放到了池中,所以在s2被创建的时候,程序找到了具有相同值的 s1
    将s2引用s1所引用的对象"Monday"
    第二段程序中,使用了 new 操作符,他明白的告诉程序:"我要一个新的!不要旧的!"于是一个新的"Monday"Sting对象被创建在内存中。他们的值相同,但是位置不同,

    2.equals

    所有类都是继承于Object这个超类的,有一个equals()方法

    这个方法很简单,就是比较对象的内存地址的。所以对象没有重写这个方法时,默认使用此方法,即比较对象的内存地址值。
    下面来看下String类重写的方法

     可以看出,String的equals()方法仅仅是对比它的 数据值,而不是对象的内存地址,所以不管String对象的内存地址是否相同并不影响其结果,equals()比较的仅仅是数据值。

     不只是String重写来equals,Double,Integer,Long....都重写了(去看源代码),所以都是比较数据值

    Integer a = 1;
    Integer b = 1;
    System.out.println(System.identityHashCode(a));
    System.out.println(System.identityHashCode(b));
    System.out.println(a.equals(b)); true

    总结

    equals()和==的区别:

    ==

    基本类型:对比它们的值是否相等

    引用类型:对比它们的内存地址是否相等

    equals()

    引用类型:默认情况下,对比它们的地址是否相等;前提是要类型都相同,如果equals()方法被重写,则根据重写过程来比较














  • 相关阅读:
    聊聊面试-NoClassDefFoundError 和 ClassNotFoundException 区别
    聊聊面试-int和Integer的区别
    数据库char varchar nchar nvarchar,编码Unicode,UTF8,GBK等,Sql语句中文前为什么加N(一次线上数据存储乱码排查)
    SQL Server数据库阻塞,死锁查询
    数据误操作,教你使用ApexSQLLog工具从 SQLServer日志恢复数据!
    IDEA将Maven项目中指定文件夹下的xml等文件编译进classes
    Tomcat 中文乱码,设置UTF-8
    C#实现前向最大匹、字典树(分词、检索)
    23种设计模式汇总
    Head First设计模式——原型模式和访问者模式
  • 原文地址:https://www.cnblogs.com/zjtao/p/12147358.html
Copyright © 2011-2022 走看看