JAVA- 浅谈==与equal()的区别

2023-05-16

目录

>基础

>基本数据类型

>引用数据类型

>Java内存

>区别==和equals()

 >==

>equals()

>总结


>基础

要想区分这两者,我们得先明白什么是基本数据类型和引用数据类型,以及Jav的内存构成

>基本数据类型

这八种数据变量中直接存储值。

>引用数据类型

引用数据类型非常多,大致包括:
类、 接口类型、 数组类型、 枚举类型、 注解类型、 字符串型

例如,String类型就是引用类型。
简单来说,所有的非基本数据类型都是引用数据类型。

>Java内存

Java内存模型中存在这两种内存区域:一种是栈内存,一种是堆内存。 (注:程序计数器,运行时数据区,永久代,直接内存这里不讨论,因为java对象保存在栈内存(基本数据类型)和堆内存(引用数据类型和包装类)中

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

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

栈只是存放基本类型的变量数据和对象的引用,但对象本身不存放在栈中,而是存放在堆(new 出来的对象)或者常量池中(字符串常量对象存放在常量池中。)

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

>区别==和equals()

 ==比较的是两个对象的地址,而equals比较的是两个对象的内容。

举个通俗的例子来说,
==是判断两个人是不是住在同一个地址
而equals是判断同一个地址里住的人是不是同一个

 >==

1)对于基本数据类型的变量, ==是直接对其值进行比较
2)对于引用数据类型的变量,则是对其内存地址的比较

下面来看一个有趣的例子:

public class deng {
    public static void main(String[] args) {
        Integer a =100;
        Integer b =100;
        Integer c =1000;
        Integer d =1000;
        System.out.println(a==b); //true
        System.out.println(c==d); //false
    }
}

这是因为Integer对象除了可以通过new来创建,也可以直接将int值赋给Integer变量,系统会自动将这个int值封装成一个Integer对象。
如:Integer a = 100;实际上的操作是:Integer a = Integer.valueof(100);

high的值为127,low的值为-128,当进行这个方法时如果值在-128-127之间,返回的值也就是地址是相同的.

这里有一个需要注意的地方:在上面Integer的valueof()方法里面,当int值范围在-128—127之间时,会通过一个IntegerCache缓存来创建Integer对象;当int值不在该范围时,直接调用new Integer()来创建对象。因此会产生以下情况:

(1)Integer a = 100;Integer b = 100;a == b为True。
因为这两个Integer变量引用的是缓存中的同一个Integer对象。

(2)Integer c = 1000; Integer d = 1000;c == d为False。
这似乎因为这两个Integer变量引用的是通过new创建的两个不同对象。

>equals()

1)基本类型不是对象,所以没有equals方法。
2)对于引用数据类型的变量,则是对其内容的比较

我们知道任何类都继承Object类,这里我们先看下object类里的equals方法:

我们可以从这段源码看出,在没有重写equals方法之前,equals方法里是直接调用==,因此实质上与==没有差别。但是要注意:equals方法不能作用于基本数据类型的变量,这是因为基本数据类型非对象的缘故,没有方法。

然而,在一些类库当中这个方法被重写了比如String 、Date、ArrayList等类,这样就不在是去比较在堆内存中的存放地址了。这里我们可以看下String类里equals方法的重写: 

从上面可以看出,先用==判断对象的地址是否相等,相等则返回true。

       如果前面的判断不成立,接着判断括号内的对象上是否是String类型,接着判断两个字符串对象的的长度是否相等,最后判断内容是否相等,如果相等则返回true。

再来一道例题测试一下吧~

public class deng {
    public static void main(String[] args) {
        String s1,s2;
        s1 = new String("嗯");
        s2 = new String("嗯");
        System.out.println(s1.equals(s2));  //true
        System.out.println(s1==s2);         //false
        String s3,s4;
        s3 = "嗯";
        s4 = new String("嗯");
        System.out.println(s3.equals(s4));  //true
        System.out.println(s3==s4);         //false
        String s5,s6;
        s5 = "嗯";
        s6 = "嗯";
        System.out.println(s5.equals(s6));  //true
        System.out.println(s5==s6);         //true
    }
}

>总结

1)对于==,一般比较的是值是否相等
     如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等;
     如果作用于引用类型的变量,则比较的是所指向的对象的地址

2)对于equals方法,一般为比较内容是否相同
     如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;
     诸如String、Date等类对equals方法进行了重写的话,比较的是所指向的对象的地址/内容。

3)若 == 为true,则equals必为true
     若equals为false,则 == 必为 false

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA- 浅谈==与equal()的区别 的相关文章

随机推荐

  • 使用VNC远程控制树莓派的Ubuntu20.04(arm)

    一 将PC与树莓派连接到同一个局域网内 比如 xff1a 将树莓派和PC连接到同一个wifi中 xff0c 方法一 xff1a 如果是家用wife发射器 xff0c 则可以在浏览器中输入 xff1a http 192 168 0 1 来查询
  • vue笔记

    ES6相关补充 var 没有块级作用域 let 有块级作用域 ES5之前因为if和for都没有块级作用域的概念 xff0c 只能借助function的作用域来解决应用外面变量的问题 let有if和for的块级作用域 变量作用域 xff1a
  • python3字符串

    Python3 字符串 字符串是 Python 中最常用的数据类型 我们可以使用引号 或 来创建字符串 创建字符串很简单 xff0c 只要为变量分配一个值即可 例如 xff1a var1 61 Hello World var2 61 Run
  • html思维导图

    标题标签 标题标签 h1 h5 xff0c 字体从大到小 对应英文语义headline 使用注意 xff1a 标题里的文字要xian想水平居中或者垂直居中得用text align和line height来做 xff0c 内外边距不行 xff
  • 什么是MVVM?

    什么是MVVM MVVM是Model View ViewModel的缩写 MVVM是一种设计思想 View层是视图层 xff0c 也就是用户界面 前端主要由HTML和CSS来构建 xff1b Model层 是指数据模型 xff0c 泛指后端
  • Docker——Windows版本Docker安装

    目录 一 简介 1 1 Docker如何解决大型项目依赖关系复杂 xff0c 不同组件依赖的兼容性问题 xff1f 1 2 Docker如何解决开发 测试 生产环境有差异的问题 1 3 Docker 和 虚拟机的区别 1 4 Docker架
  • 细说C++中的 :: 和 : 的区别

    C 43 43 中的 1 类的作用域 作用域符号 的前面一般是类名称 xff0c 后面一般是该类的成员名称 xff0c C 43 43 为例避免不同的类有名称相同的成员而采用作用域的方式进行区分 假如 xff1a A B表示两个类 xff0
  • 扰动观测器(DOB)设计

    snf 机器人机械手可能会受到不同类型的干扰 例如未知的有效载荷 未建模的动力学和环境相互作用力 观察机器人操纵器中的这些未知干扰是许多机器人应用的基础 例如干扰抑制和无传感器力控制 机械手在进行正常操作时可能会受到不同类型的干扰 粗略地说
  • Gazebo安装教程——在 Ubuntu 上安装Gazebo的源代码

    安装工具 建议使用一些额外的工具来帮助编译源代码 xff0c 尽管其他正确获取和构建源代码的方法也是可能的 获取所有库的源代码的最简单方法是使用 vcstool 要以正确的顺序编译所有不同的库和 ign gazebo xff0c 建议使用c
  • 线性与非线性控制

    控制理论领域可以分为两个分支 xff1a 线性控制理论 这适用于由遵循叠加原理的设备组成的系统 xff0c 这大致意味着输出与输入成正比 它们由线性微分方程控制 一个主要的子类是另外具有不随时间变化的参数的系统 xff0c 称为线性时不变
  • 模型预测控制(Model predictive control,MPC)

    模型预测控制 MPC 是一种先进的过程控制方法 xff0c 用于在满足一组约束条件的同时控制过程 自 1980 年代以来 xff0c 它一直在化工厂和炼油厂的加工工业中使用 近年来 xff0c 它还被用于电力系统平衡模型 1 和电力电子学中
  • 蓝桥杯单片机官方测试程序现象

    IO模式 xff0c 矩阵按键下 xff1a 开机次数 测试AT24C02 S7 测试LED 按2次 S11 测试DAC 按4次 S15 测试ADC双通道 按2次 S19 测试超声波 S6 测试温度模块 S10 0 测量 S14 测试继电器
  • 51单片机的1T和12T的区别

    1T 模式 不分频 1个系统基本时钟 xff0c 执行一个动作 xff1b 12T模式 12分频 12个系统基本时钟 xff0c 执行一个动作 xff1b 因此 xff0c 12T模式和1T模式执行相同次数的动作 xff0c 12T模式需要
  • python2数据类型

    Python3 数字 Number Python 数字数据类型用于存储数值 数据类型是不允许改变的 这就意味着如果改变数字数据类型得值 xff0c 将重新分配内存空间 以下实例在变量赋值时 Number 对象将被创建 xff1a var1
  • keil中的extern的使用

    C51头文件使用extern的目的是外部变量或函数声明 使用时要注意 1 extern最好写在 h文件中 xff0c 方便后期的可读性 2 在使用extern进行外部变量声明时 xff0c 不能重新给变量赋值 例如 xff1a extern
  • STC89C52RC/RD中定时器2的使用方法

    学过一段时间单片机的你发现 xff0c 中断服务函数可以在主函数进行的同时 xff0c 进行一些对时间要求高的模块的配置时 xff0c 则要用到定时器中断 而如果你要实现多个功能的操作 xff0c 会使用多个定时器是必要的STC89C51单
  • keilC51中调试的方法(主要介绍串口调试XCOM)

    在keilC51中调试的方法的方法有很多 xff1a 1 直接看现象 2 串口调试 3 debug调试 下面终点讲串口调试 xff1a 若要实现printf重定向 重写printf调用的putchar函数 xff0c 重定向到串口输出 需要
  • data/xdata/pdata/code

    dada最大在128byte xff0c 不然就会报错 data xdada最大在512byte xff0c 不然就会报错 xdata pdata stc89c52中未使用 code xff08 将ROM内的定值存在程序存储器中 xff0c
  • 基于PID算法(python)的飞控设计学习日志(一)

    PID算法基础 首先我们需要去了解PID算法的数学原理 xff0c 数学原理部分借鉴于 64 确定有穷自动 机 的博客 一文读懂PID控制算法 xff08 抛弃公式 xff0c 从原理上真正理解PID控制 xff09 总的来说 xff0c
  • JAVA- 浅谈==与equal()的区别

    目录 gt 基础 gt 基本数据类型 gt 引用数据类型 gt Java内存 gt 区别 61 61 和equals gt 61 61 gt equals gt 总结 gt 基础 要想区分这两者 xff0c 我们得先明白什么是基本数据类型和