前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >[Jave]详解"equals方法"和"==操作符"

[Jave]详解"equals方法"和"==操作符"

作者头像
祥知道
发布2020-03-10 14:51:12
2980
发布2020-03-10 14:51:12
举报
文章被收录于专栏:祥的专栏

原创文章,欢迎转载。转载请注明:转载自 祥的博客

原文链接:http://blog.csdn.net/humanking7/article/details/43583643

总纲

其实equals()方法==操作符的区别就是下面两句话:

  • 操作符 == 是用来比较两个引用是否指向堆内存当中的同一块地址
  • equals(Object obj) 方法是用来比较两个对象的值是否相等

详细分析

操作符”==”的作用

预备知识

看到一段不错的讲解,截取如下:

Java把内存分成两种,一种叫做栈内存,一种叫做堆内存

在函数中定义的 一些基本类型的变量和对象的引用变量 都是在函数的栈内存中分配。当在一段代码块中定义一个变量时,java就在栈中为这个变量分配内存空间,当超过变量的作用域后,java会自动释放掉为该变量分配的内存空间,该内存空间可以立刻被另作他用。

堆内存用于存放由new创建的对象和数组。在堆中分配的内存,由java虚拟机自动垃圾回收器来管理。在堆中产生了一个数组或者对象后,还可以在栈中定义一个特殊的变量,这个变量的取值等于数组或者对象在堆内存中的首地址,在栈中的这个特殊的变量就变成了数组或者对象的引用变量,以后就可以在程序中使用 栈内存中的引用变量来访问堆中的数组或者对象,引用变量相当于为数组或者对象起的一个别名,或者代号

引用变量是普通变量,定义时在栈中分配内存,引用变量在程序运行到作用域外释放。而数组&对象本身在堆中分配,即使程序运行到使用new产生数组和对象的语句所在地代码块之外,数组和对象本身占用的堆内存也不会被释放,数组和对象在没有引用变量指向它的时候,才变成垃圾,不能再被使用,但是仍然占着内存,在随后的一个不确定的时间被垃圾回收器释放掉,这个也是java比较占内存的主要原因。

实际上,栈中的变量 指向 堆内存中的变量,这就是 Java中的指针!

举例

  • 对于基本数据类型 基本数据类型也称原始数据类型,即就是 byte,short,char,int,long,float,double,boolean 他们之间的比较,应用双等号操作符 ==,比较的是他们的值。
  • 对于复合数据类型(类)双等号操作符 ==进行比较的时候,比较的是他们在(栈)内存中的存放地址(是否指向同一块堆内存地址),所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false。

大家看下面一段代码:

代码语言:javascript
复制
    User u1 = new User();
    User u2 = new User();
    User u3 = u1;
    boolean flag1 = (u1 == u2);
    boolean flag2 = (u1 == u3);

运行结果是:

代码语言:javascript
复制
flag1 是 false
flag2 是 true

内存分配如下:

“equals()”方法的作用

预备知识

简单的的来说,equals() 是用来比较两个对象的内容是否相等

对象的内容相等需要符合两个条件

  1. 对象的内容相同( 可以使用instanceof操作符进行进行比较 );
  2. 两个对象的成员变量的完全相同。

(有没有特例? 我不清楚,希望大家告诉我)

举例

大家看一下下面这段代码:

代码语言:javascript
复制
    public class User{

        String name;
        int age;

        @Override
        public boolean equals(Object obj) { 
            if (this == obj) {
                //如果当前对象和判断的对象指向同一个堆内存地址,那么肯定内容相等
                return true;
            }

            //被判断对象是不是User类型
            boolean flag = obj instanceof User;     
            if(flag){
                User u = (User)obj;
                if((this.age == u.age) && (this.name.equals(u.name) )){
                    //age是基本类型,name是String类型得用equals()判断是不是内容相等
                    return true;
                }           
            }
            //其他情况都是内容不同
            return false;
        }

        public static void main(String[] args) {
            User u1 = new User();
            User u2 = new User();
            User u3 = new User();
            User u4 = u1;//指向堆内存同一个对象

            u1.name = "QiaoGe";
            u1.age = 18;

            u2.name = "XiangGe";
            u2.age = 24;

            u3.name = "QiaoGe";
            u3.age = 18;

            System.out.println(u1.equals(u2));//false:内容不同
            System.out.println(u1.equals(u3));//true:内容相同
            System.out.println(u1.equals(u4));//true:指向堆内存同一个对象     
        }
    }

运行结果如下:

代码语言:javascript
复制
false
true
true

总结

其实没有比总纲说的更好的,照搬总纲,哇咔咔

equals()方法==操作符的区别就是下面两句话:

  • 操作符 == 是用来比较两个引用是否指向堆内存当中的同一块地址
  • equals(Object obj) 方法是用来比较两个对象的值是否相等

参考文献

  • [1] Mars老师的“Java4Android”
  • [2] Java中堆内存和栈内存详解:www.cnblogs.com/whgw/archive/2011/09/29/2194997.html
  • [3] JDK Documentation
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 总纲
  • 详细分析
    • 操作符”==”的作用
      • 预备知识
      • 举例
    • “equals()”方法的作用
      • 预备知识
      • 举例
  • 总结
  • 参考文献
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档