4.基本数据类型与包装类型

本文深入探讨了Java中的包装类型,包括为何需要包装类、自动装箱与拆箱原理、基本数据类型与包装类的==与equals区别。此外,文章还提及了阿里巴巴开发手册中的相关规约,强调在特定情况下应使用equals方法。最后,举例说明了包装类在实际编程中的应用,如获取最大最小值、字符串转换等,并推荐使用valueOf方法以优化性能。
摘要由CSDN通过智能技术生成

1. 为什么要有包装类型?

个人理解

  1. 这是为了弥补基本数据类型的不足 如果你在集合中使用 是无法放入 int long 之类的类型的 所以需要一个桥梁 为了泛型而考虑
  2. 这也是为了保证面向对象的完整性 当你需要将字符串"1123" 转化为 int 类型 发现无从下手了 所以包装类可以提供一系列的属性方法 增强基本数据类型
  3. 数据缓存 当Integer类型在 -128~127之间时 会从缓存区去取 作者可能是考虑到这个范围的数比较常用而考虑的吧
  4. 某些时候我们并不希望一些数值有默认值 即便是0也不想要 我们只希望它为空 而基本数据类型大多默认值为0 而包装类默认就是为null 的

2. 自动装箱与拆箱

自动装箱:能够将基本数据类型包装起来变成特定的包装类,无需其他操作

自动拆箱:能够将包装类型转化为基本数据类型,同样无需其他操作

这两点都体现在自动

如下所示 轻易就能够转换过去

Integer a=10;
int b = new Integer(20);

让我们探究下内部做了什么操作

通过打断点的方式 我们找到了对应的代码

以下是自动装箱的源码 其实真正调用的是valueOf 方法实现的

  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

简单的说下 装箱会从缓存区去取值 如果找的到 直接返回 找不到就new 一个Integer 返回

自动拆箱的代码就更简单了 自动调用initValue 方法 返回 int类型的 value

   public int intValue() {
        return value;
    }

3. 基本数据类型与包装类的==与equals

这样一个面试题想必大家都不陌生

Q1: 请说一下==与equals的区别?

对于基本数据类型 只能用== 来比较两个数值是否相等了 它也想调用equals 方法啊

奈何
在这里插入图片描述
其实说白了 ==比较的是内存中的地址 我们常用的 1 2 3 4 5 这些数字

一旦被使用 就会被放入常量池中 下一次使用 指向的还是那个位置 所以一定会相等

但如果是包装类型 就不一定了 用== 可能会相等 可能是不相等的 引出之前提到的常量池技术

  public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

之前这里没有细讲

IntegerCache.low=-128

IntegerCache.high=127

其实 high的值并不是固定的 可以在jvm参数中设置 但一般我们不做设置 所以就是在这个范围以内

其他类型也实现了常量池技术 Byte,Short,Integer,Long 这 4 种包装类默认创建了数值 [-128,127]的相应类型的缓存数据,

Character创建了数值在[0,127]范围的缓存数据,Boolean 直接返回 TrueFalse

Float,Double 没有实现常量池技术

所以下面的题目应该会做了吧?

Integer a=120;
Integer b=120;
System.out.println(a==b);

Integer c = 130;
Integer d = 130;
System.out.println(c==d);

很简单 分别打印 truefalse 需要注意一点 一旦使用了 new 就会在堆里面再开辟出一片空间 所以内存地址肯定是不一样的了

再说说 equlals方法

我们进入 Object 类 查看源码

  public boolean equals(Object obj) {
        return (this == obj);
    }

发现了什么? 竟然也是用的 == 不对啊 怎么跟我们想象的不一样

因为我们看的是最高级的父类 Object 一般我们都会覆盖equals 方法

我们再看一下 Integer 类的源码

 public boolean equals(Object obj) {
 		//①
        if (obj instanceof Integer) {
        	//②
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

在 ① 处 首先会判断下 比较的对象是否是 Integer类或者是其子类(当然Integer不可被继承 所以就限定是这个类)
否则就不比较直接返回false

在 ② 处 会将对应的对象转化为Integer类 再拆箱 比较两者是否相等

其实Integer 类的 equals 方法很简单 没什么复杂的操作 以后我们再分析字符串的equals 方法

接下来该回答一下前面的问题了

A1:

  1. 对于基本数据类型 只能使用==比较两个值是否相等 其实比较的就是两个变量的内存地址是否相同
  2. 对于其他引用类型==equlals都可以使用 默认Objectequals方法比较的就是两个对象的内存地址
    一般的常用类都会重写equals方法,从而可以实现比较两个对象的某个特定内容是否相等
    对于我们自定义的类 都需要我们自己重写一下 equals方法,否则默认使用的还是==

4. 阿里巴巴开发手册规约

我再将阿里巴巴开发手册关于包装类型有关的规约发一下

因为有缓存区 所以一律使用equals
在这里插入图片描述
这个后面会讲到关于浮点类型的比较
在这里插入图片描述

定义一些pojo 类的时候 建议使用包装类型 因为可能值可能为null
在这里插入图片描述
返回类型要一致
在这里插入图片描述

5. 其他

有了包装类型 我们可以调用一些方法来简化我们的操作

比如定义 int 类型的最大最小值

int a = Integer.MAX_VALUE;
int b = Integer.MIN_VALUE;

将字符串转化为对应的整型
int s=Integer.parseInt("11223");

同样的将 int 类型或者字符串转化为包装类

一种是 new 一种是使用valueOf

int a1 = new Integer("213");
int a2 = Integer.valueOf("213");

int b1 = new Integer(213);
int b2 = Integer.valueOf(213);

推荐使用第二种方法 因为第一种必定会创建新的对象 而第二种可能直接用缓存区里的值 且可能还会有后续优化

要是你老是认为自己配不上一个更好的人,
那么,你也永远无法成为一个更好甚至最好的自己。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值