==与equals源码角度分析

2021/12/2 17:39:05

本文主要是介绍==与equals源码角度分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

分析前基础了

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

   ①在函数中定义的一些基本类型的变量和对象的引用变量(变量名)都在函数的栈内存中分配。

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

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

二)Object类中的equals方法:

public boolean equals(Object obj) {
return (this == obj);
}// 可以看出Object类中equals方法是用==判断对象引用是否指向同一内存地址。

三)String类很特殊 ,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;
}//可以看出在String类中equals方法不仅可以用==判断对象的内存地址是否相等,相等则返回true。如果前面的判断不成立,接着判断括号内的对象上是否是String类型,接着判断两个字符串对象的的长度是否相等,最后判断内容是否相等,如果相等则返回true。

四)开始具体分析:

4.1 在基本数据类型中的比较
int num1 = 10;
int num2 = 10;
System.out.println(num1 == num2); //true
//num1 和num2都是int型 它们的值都是10,因此使用”==”当然相等.

4.2 在引用数据类型中的比较
⑴String s1 = "hello";
String s2 = "hello";
System.out.println(s1 == s2); // true
System.out.println(s1.equals(s2)); // true

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

 接着System.out.println(s1.equals(s2));这里的equals在String类中被重写过,用来比较两个字符串的实际内容是否相等,即每一个字符是否相等,重写方法末尾会另做说明!!!因为比较的是字符串内容,s1,s2内容都是hello当然是相等的。 
 
(2) String ss1 = "aaa";
         String ss2 = new String("aaa");
         System.out.println(ss1 == ss2);  //false
         System.out.println(ss1.equals(ss2));  // true
 
ss2是new出来的,所以重新分配内存地址,当用==判断时,返回false,但是两个字符串的内容相同,所以用equals方法时,返回true。

 

 接着System.out.println(s1.equals(s2));这里的equals在String类中被重写过,用来比较两个字符串的实际内容是否相等,即每一个字符是否相等,重写方法末尾会另做说明!!!因为比较的是字符串内容,s1,s2内容都是hello当然是相等的。 
 
(2) String ss1 = "aaa";
         String ss2 = new String("aaa");
         System.out.println(ss1 == ss2);  //false
         System.out.println(ss1.equals(ss2));  // true
 
ss2是new出来的,所以重新分配内存地址,当用==判断时,返回false,但是两个字符串的内容相同,所以用equals方法时,返回true。

(3)String sss1 = new String("aaa");
String sss2 = new String("aaa");
System.out.println(sss1 == sss2); //false
System.out.println(sss1.equals(sss2)); // true 

sss1和sss2都为new出来的对象,各占有一块内存空间,所以内存地址不同,但是字符串内容相同。

 (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

 "=="操作符的作用

1、用于基本数据类型的比较

2、判断引用是否指向堆内存的同一块地址。

equals所在位置:

在Object类当中,而Object是所有类的父类,包含在jdk里面,但并不适合绝大多数场景,通常需要重写

  1. public boolean equals(Object obj) {

  2. return (this == obj);

  3. }

equals的作用:

用于判断两个变量是否是对同一个对象的引用,即堆中的内容是否相同,返回值为布尔类型

equals的基本使用:

boolean b = obj1.equals(obj2);

String类型比较不同对象内容是否相同,应该用equals,因为==用于比较引用类型和比较基本数据类型时具有不同的功能。

分析如下:

String作为一个对象来使用

例子一:对象不同,内容相同,"=="返回false,equals返回true

  1. String s1 = new String("java");

  2. String s2 = new String("java");

  3. System.out.println(s1==s2); //false

  4. System.out.println(s1.equals(s2)); //true

例子二:同一对象,"=="和equals结果相同

  1. String s1 = new String("java");

  2. String s2 = s1;

  3. System.out.println(s1==s2); //true

  4. System.out.println(s1.equals(s2)); //true

String作为一个基本类型来使用

如果值不相同,对象就不相同,所以"==" 和equals结果一样

  1. String s1 = "java";

  2. String s2 = "java";

  3. System.out.println(s1==s2); //true

  4. System.out.println(s1.equals(s2)); //true

如果String缓冲池内不存在与其指定值相同的String对象,那么此时虚拟机将为此创建新的String对象,并存放在String缓冲池内。

如果String缓冲池内存在与其指定值相同的String对象,那么此时虚拟机将不为此创建新的String对象,而直接返回已存在的String对象的引用。

 



这篇关于==与equals源码角度分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程