首页 > 其他分享 >== 和 equals 的区别

== 和 equals 的区别

时间:2024-07-29 21:27:34浏览次数:10  
标签:区别 对象 System equals println Integer out

在Java中,==equals() 是用于比较对象的两种不同方法,它们有着不同的作用和用途:

  1. == 运算符

    • == 运算符用于比较两个对象的引用(内存地址)是否相同。

    • 如果两个引用指向内存中的同一个对象,则 == 返回 true

    • 对于基本数据类型,== 则用于比较它们的值是否相等。

    示例:

    String str1 = new String("hello");
    String str2 = new String("hello");
    String str3 = str1;
    ​
    System.out.println(str1 == str2);  // false,因为str1和str2引用的是不同的对象
    System.out.println(str1 == str3);  // true,因为str1和str3引用的是同一个对象

  2. equals() 方法

    • equals() 方法用于比较对象的内容是否相等(逻辑相等)。

    • equals() 方法是Object 类中定义的方法,因此所有的Java类都继承了这个方法。

    • 默认情况下,equals() 方法的行为与 == 运算符相同,即比较两个对象的引用是否相同。

    • 但是,许多类(如 String, Integer 等)会重写 equals() 方法,以便比较对象的内容而不是引用。

    示例:

    String str1 = new String("hello");
    String str2 = new String("hello");
    ​
    System.out.println(str1.equals(str2));  // true,因为String类重写了equals方法,比较的是内容

误区

public class JavaBase {
    public static void main(String[] args) {
        //测试==和equals的区别
//        int a = 128;
//        Integer b = 128;
//        System.out.println(a == b);
//        System.out.println(b.equals(a));
​
//        int c = 127;
//        Integer d = 127;
//        System.out.println(c == d);
//        System.out.println(d.equals(c));
​
//        int a1 = 128;
//        Integer b1 = new Integer(128);
//        System.out.println(a1 == b1);
//        System.out.println(b1.equals(a1));
​
//        int c1 = 127;
//        Integer d1 = new Integer(127);
//        System.out.println(c1 == d1);
//        System.out.println(d1.equals(c1));
//        以上输出结果全为true
​
        Integer a2 = -128;
        Integer b2 = -128;
        System.out.println(a2 == b2);//true
        System.out.println(a2.equals(b2));//true
​
​
        Integer a21 = -129;
        Integer b21 = -129;
        System.out.println(a21 == b21);//false
        System.out.println(a21.equals(b21));//true
​
        Integer a3 = new Integer(-128);
        Integer b3 = new Integer(-128);
        System.out.println(a3 == b3);//false
        System.out.println(a3.equals(b3));//true
​
        Integer a31 = new Integer(-129);
        Integer b31= new Integer(-129);
        System.out.println(a31 == b31);//false
        System.out.println(a31.equals(b31));//true
    }
}

对于上面的结果,为什么相同的逻辑,输出结果却不同呢?

在Java中,对于整数对象的比较,特别是Integer对象,存在一个称为整数缓存(Integer Cache)的机制,它对范围在 -128127 之间的整数进行了特殊处理。这个范围是根据Java虚拟机的实现而定,通常是为了提高性能和节省内存。

具体来说,当你创建一个 Integer 对象时,如果其值在 -128127 范围内,Java会检查是否已经存在该值对应的 Integer 对象。如果存在,就直接返回缓存中的对象;如果不存在,就创建一个新的 Integer 对象,并将其放入缓存中。

因此,对于范围在 -128127 之间的整数,使用 == 运算符比较两个 Integer 对象时,会直接比较它们的引用地址。由于它们引用的是同一个对象(如果值相同的话),因此 == 比较会返回 true

这种整数缓存机制在日常开发中有助于提高性能,因为频繁使用的小整数不会反复创建新的对象,而是复用已有的对象。但是,需要注意的是,这种优化只适用于 Integer 对象,对于 int 基本数据类型,直接使用 == 比较的是它们的值,而不是引用。

总结来说,范围在 -128127 之间的整数使用 == 比较可以得到正确的结果,是因为它们可能引用同一个对象,这是由Java虚拟机的实现和整数缓存机制所决定的。

从堆栈存储的角度进行分析:

  1. Heap(堆)

    • 堆是Java中用于存储对象的主要内存区域。所有通过 new 关键字创建的对象,无论是 Integer 还是其他类的实例,都存储在堆中。

    • 对于 Integer 对象,如果其值在 -128127 范围内,Java会使用整数缓存机制(也是存储在堆里面的),从而在堆中复用已经存在的对象。

  2. Stack(栈)

    • 栈是Java线程私有的内存区域,用于存储局部变量、方法调用和部分对象引用。

    • 对于基本数据类型的变量(例如 int),其值通常直接存储在栈中,而不是存储在堆中。

整数缓存与堆和栈的关系可以总结如下:

  • 整数缓存机制是针对 Integer 对象在堆中的存储优化。范围在 -128127 之间的整数会被缓存,这些对象可以在堆中被复用,而不是每次都创建新的对象。

  • 当使用 == 比较两个范围内的 Integer 对象时,实际上是在比较它们在堆中的引用地址。因为整数缓存使得相同值的 Integer 对象可以共享同一个对象实例,所以 == 比较可以返回 true

因此,整数缓存机制的优化和堆栈的概念虽然相关,但具体来说,它主要是与堆中 Integer 对象的创建、复用及其对比方式有关,而不是直接与栈的内存分配机制有直接关系。

标签:区别,对象,System,equals,println,Integer,out
From: https://blog.csdn.net/weixin_64618449/article/details/140781550

相关文章

  • 都是全志T113处理器,“-i”和“-S3”有什么区别?
    自9个月前,创龙科技“1片含税就79元”的全志T113-i双核[email protected]的工业核心板(SOM-TLT113)推出之后,不少嵌入式软硬件工程师、用户都咨询我们,究竟T113-i和T113-S3这两款处理器有什么区别?不同后缀型号的处理器,哪个更适合工业场景?今天,创龙科技就为大家深度揭秘,详细讲解......
  • 大模型面经之bert和gpt区别
            BERT和GPT是自然语言处理(NLP)领域中的两种重要预训练语言模型,它们在多个方面存在显著的区别。以下是对BERT和GPT区别的详细分析。一、模型基础与架构BERT:全称:BidirectionalEncoderRepresentationsfromTransformers。架构:基于Transformer的编码器部......
  • find 命令中使用 -exec 和xargs 区别, 以及使用案例
    一、概念释义find 命令是Linux和Unix系统中用于查找文件的强大工具。它允许你根据各种条件(如文件名、大小、类型、权限等)来搜索文件。在使用 find 命令时,-exec 和 xargs 是两种常用的方式来对找到的文件执行额外的命令。尽管它们的目的相似,但在使用方式和效率上存在一......
  • 常见的LVS模式区别
    几种常见的LVS(LinuxVirtualServer)模式:NAT模式、IP地址转发(DirectRouting)模式和IP隧道(Tunneling)模式的区别:1.NAT模式特点:LVS作为前端代理,接收客户端的请求,并修改数据包的目标地址和端口,然后将请求转发给后端的真实服务器。后端服务器返回的响应经过LVS再修改为源地......
  • 设计模式:代理、装饰和适配器模式的区别
    结构对比讲实话,博主当初学习完整设计模式时,这三种设计模式单独摘哪一种都是十分清晰和明确的,但是随着模式种类的增加,在实际使用的时候竟然会出现恍惚,例如读开源代码时,遇到不以模式命名规范的代码时,一时难以说清具体是使用的这三种里的哪一种。之所以会出现混淆的原因是,三种模式......
  • 简单聊聊JavaScript 中的原型链、null 和 undefined 的区别
    1.原型链个人观点:原型链和逻辑判断里三段论有些类似,一个大前提、一个小前提、一个结论。比如,动物会吃肉,狗是动物,所以狗会吃肉。这也是继承的思想原型和构造函数JavaScript是基于原型的面向对象编程语言,每个对象都有一个内部链接到另一个对象(即原型)。这个机制被称为原型链。原......
  • 在SQL编程中DROP、DELETE和TRUNCATE的区别
    在SQL编程中,DROP、DELETE和TRUNCATE都是用于删除数据的命令,但它们之间有着显著的区别,主要体现在它们删除数据的范围、操作的不可逆性、对表结构的影响、性能以及事务日志的影响上。DROP:作用:DROP命令用于删除整个表及其所有的数据、索引、触发器、约束等。简而言之,它会从......
  • C++中 cin、cin.get()、cin.getline()、getline() 的区别
    cin我们先介绍c++中最常用的输入流对象cin我们常用 cin>>num 来从缓冲区中读取数据到 num 中,num 的变量类型可以是多种类型,最常用的有 int、string、char、double、float等等voidcin_test(){std::cout<<"-----------cintest---------"<<std::endl;st......
  • 15 赋值、浅拷贝和深拷贝区别_is和==的区别
     欢迎来到@一夜看尽长安花博客,您的点赞和收藏是我持续发文的动力对于文章中出现的任何错误请大家批评指出,一定及时修改。有任何想要讨论的问题可联系我:[email protected]。发布文章的风格因专栏而异,均自成体系,不足之处请大家指正。   专栏:java全栈C&C++PythonAIP......
  • nginx 配置代理服务地址最后多加反斜杠和不加反斜杠的区别
    在使用Nginx配置代理服务时,地址最后是否添加反斜杠(/)会对代理的URL处理产生影响。1.地址最后不加反斜杠当配置的代理服务地址最后没有反斜杠时,Nginx会将请求的URL路径原封不动地传递给后端服务器。例如:location/backend/{proxy_passhttp://backend-server;}请......