【Java基础】"=="和equals区别

对于基本类型

对于基本数据类型:(byte,short,char,int,float,double,long,boolean),比较的是

  • 他们是作为常量方法区中的常量池里面以HashSet策略存储起来的,对于这样的字符串 “123” 也是相同的道理,在常量池中,一个常量只会对应一个地址,因此不管是再多的 123,“123” 这样的数据都只会存储一个地址,所以所有他们的引用都是指向的同一块地址,因此基本数据类型String常量是可以直接通过==来直接比较的

对于引用类型

对于引用数据类型 ,有equals和==两种方法比较

  1. ==比较的是引用的内存地址值
  2. equals方法,是object中的方法,如果不重写的话,比较的也是引用的内存地址值,实际和==一样。
  3. 如果自己所创建的类中已经重写equals方法,那么就在equals内以我们自定义的方式来比较俩个对象是否相等,
  4. 如果没有重写过equal方法,那么会调用父类(Object)中的equals方法进行比较,也就是比较地址值,就是是 == 。

==与equals与内存有关

JVM把内存划分成两种:一种是栈内存,一种是堆内存

  1. 在方法中定义的一些基本类型的变量对象的引用变量(变量名)都在方法的栈内存中分配。

  2. 当在一段代码块声明一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配的内存空间,该内存空间可以立即被另作他用。

  3. 堆内存用来存放由new创建的对象(包括由基本类型包装起来的类:Integer、String、Double,实际上每个基本类型都有他的包装类)和数组。

Object和String类的equals源码解析

  1. Object类中的equals方法:

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

    可以看出Object类中equals方法是用==判断对象引用是否指向同一内存地址。所以我们创建的类类不重写equals方法, 用 equals 来比较对象, 比较的依然是是对象的内存地址。

  2. String类中的equals方法:
    在这里插入图片描述

举例说明

  1. 案例1
    String st1 = "hello";
    String  st2 = "hello";
    System.out.println( st1==st2); //true
    st1.equals(st2);//true   
    

分析:String默认已经实现了重写equals方

  1. 先比较当前对象的内存地址和要比较的对象的内存地址是否相等,若相等,则返回true否则,提前结束比较

  2. 如果内存地址不相等,则判断是否为String类型的对象,如果是,在判断长度是否相等,再判断数组的每个值,字母是否相等。如果都相等,则返回true, 如果不是String类型的对象直接返回false

  3. 上面的判断当执行String st1 = “hello”;这条语句时,会在堆中的字符常量池里找”hello”这个字符串,若没有找到,则将”hello”这个字符串放入字符串常量池中.而在栈中开辟一块名为st1的空间存放”hello”,这块空间的引用.当执行String st2= “hello”;这条语句时,会在堆中的字符串常量池里找”hello”这个字符串,很显然,可以找到,于是便把字符常量池里”hello”这个字符串的引用地址赋给st2,因此st1与 存放的都是堆中字符常量池中的同一个”hello”的引用

  4. 案例2

    String  st1 = "hello";
    String  st2 = new String("hello");
    System.out.println(st1 == st2 );  //false  因为重现new出来的,就会重新开辟一块地址,所以比较的的是引用的地址	值, false
    st1.equals(st2);//true  因为String已经重写了equals方法,比较的是值,则相等,true
    
  5. 案例3

    String st1 = new 	String("aaa");
    String st1 = new String("aaa");
    System.out.println(st1 == st2 ); //false
    System.out.println(st1.equals(st2)); // true   
    // st1和st2都为new出来的对象,各占有一块内存空间,所以内存地址不同,但是字符串内容相同。
    
  6. 案例4

    // 非String类,例如StringBuffer类 没有重写equals方法,所以不比较内容。==和equals都是比较的内存地址
    StringBuffer stringBuffer = new StringBuffer("aaa");
    StringBuffer stringBuffer2 = new StringBuffer("aaa");
    System.out.println(stringBuffer == stringBuffer2); // false
    System.out.println(stringBuffer.equals(stringBuffer2)); // false
    
发布了62 篇原创文章 · 获赞 109 · 访问量 5300

猜你喜欢

转载自blog.csdn.net/qq877728715/article/details/102952820