ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

简单的符号,不简单的对象

2022-01-21 15:03:45  阅读:116  来源: 互联网

标签:String 符号 对象 equals println 简单 类型 Integer true


Java基础面试题中"=="和"equals"的区别是什么?出现的频率还是蛮高的(听别人说的)。知道他们的作用,也就知道他们有什么区别了(这怕不是废话)。但是在使用中出现的结果有时候不是你以为的结果。主要原因是在比较的对象身上。

简单的符号

"=="和"equals"的作用是对两个对象进行比较。具体如下:

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

  • 对于equals,如果没有对equals方法进行重写,则比较的是引用类型的变量所指向的对象的地址;反之比较的则是所指向的对象的内容。

不简单的对象

基本数据类型

Java中8种基本数据类型:

  • 整型:byte(1 byte), short(2 byte), int(4 byte) , long(8 byte)

  • 浮点型:float(4 byte), double(8 byte)

  • 字符型: char(2 byte)

  • 布尔型: boolean(所占的空间大小并没有给出精确的定义,网上的回答也是五花八门)

注意:equals方法不能作用于基本数据类型的变量。

Java中的基本数据的类型的比较相对而言是最简单的。使用"=="进行比较,判断其是否相等。

String类型

点击查看代码
public static void main(String[] args) {
        //第一种创建方式
        String a = "abc" ;
        String b = "abc" ;
      	//第二种创建方式
        String c = new String("abc");
        String d = new String("abc");
        
        System.out.println(a==b);//true
        System.out.println(a.equals(b));//true  
        
        System.out.println(c==d);//false
        System.out.println(c.equals(d));//true

        System.out.println(a==c);//false
        System.out.println(a.equals(c));//true     
    }
上面的例题非常简单,对字符串"abc"进行比较。
  • 对于"equals",因为String中对equals进行了重写,比较的是对象的内容,所以比较结果都是true,对于这个结果在意料之中。
  • 对于"==",结果如果让你皱起了眉头,那就继续往下看。再次提醒其作用引用类型变量时,比较的是所指向的对象的地址。

使用第一种方式时,首先在常量池中查询并通过equals来判断是否已经存在"abc",如果有就不会创建的新的对象,直接返回已有对象的引用,由于String类被final修饰,所以它一经创建就不会被修改。也就不必担心共享而带来的问题。也就不难理解为什么a==b的结果为true。

使用第二种方式时,无论常量池中有没有"abc"字符串,都会在堆内存中开辟一片新的空间存放对象,即使堆内存中存在"abc",也会开辟一块新的空间存放对象,所以c == d 、 a == c的结果则均为false。

Integer类型

点击查看代码
public static void main(String[] args) {
        Integer i1 = 127;
        Integer i2 = 127;
        System.out.println(i1 == i2);//true
        System.out.println(i1.equals(i2));//true
        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i3 == i4);//false
        System.out.println(i3.equals(i4));//true
    }
上面已经了解了String类型,接下来我们来看下Integer类型。Integer是Java为基本类型int提供的包装类。

Java 为基本数据类型提供了对应的包装器类型

  • Integer:对应封装了基本类型 int;

  • Long:对应封装了基本类型 long;

  • Float:对应封装了基本类型 float;

  • Double:对应封装了基本类型 double;

  • Boolean:对应封装了基本类型 boolean;

  • String:对应封装了字符串类型 char[]。

包装类型与基本类型之间的相互转换称作装箱和开箱。

所谓的自动装箱,就是自动将基本数据类型转换为包装器类型。所谓的自动拆箱,也就是自动将包装器类型转化为基本数据类型。

数值是基本数据类型 int,当赋值给包装器类型(Integer)变量的时候,触发自动装箱操作,创建一个 Integer 类型的对象,并且赋值给变量。

  • 对于"equals",因为比较的是对象的内容,所以比较结果都是true,对于这个结果在意料之中。
  • 对于"==",上面提到触发自动装箱时,会创建一个对象,按这说法来看,i1 == i2、i3 == i4的结果应该都是false,为什么i1 == i2的结果是true呢?

实际上,当通过自动装箱,也就是调用 valueOf() 来创建 Integer 对象的时候,如果要创建的 Integer 对象的值在 -128 到 127 之间,会从 IntegerCache 类中直接返回,否则才调用 new 方法创建。看代码更加清晰一些,Integer 类的 valueOf() 函数的具体代码如下所示:

点击查看代码
public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}
为什么 IntegerCache 只缓存 -128 到 127 之间的整型值呢?

在 IntegerCache 的代码实现中,当这个类被加载的时候,缓存的享元对象会被集中一次性创建好。毕竟整型值太多了,我们不可能在 IntegerCache 类中预先创建好所有的整型值,这样既占用太多内存,也使得加载 IntegerCache 类的时间过长。所以,我们只能选择缓存对于大部分应用来说最常用的整型值,也就是一个字节的大小(-128 到 127 之间的数据)。

实际上,JDK 也提供了方法来让我们可以自定义缓存的最大值,有下面两种方式。如果你通过分析应用的 JVM 内存占用情况,发现 -128 到 255 之间的数据占用的内存比较多,你就可以用如下方式,将缓存的最大值从 127 调整到 255。不过,这里注意一下,JDK 并没有提供设置最小值的方法。

点击查看代码
//方法一:
-Djava.lang.Integer.IntegerCache.high=255
//方法二:
-XX:AutoBoxCacheMax=255
实际上,除了 Integer 类型之外,其他包装器类型,比如 Long、Short、Byte 等,也都利用了享元模式来缓存 -128 到 127 之间的数据。

标签:String,符号,对象,equals,println,简单,类型,Integer,true
来源: https://www.cnblogs.com/JavaUrl/p/15830062.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有