[java]-包装类

学习目标

  1. 了解包装类是什么。
  2. 了解装箱和拆箱机制
  3. 自动装箱和自动拆箱

0.为什么要学习包装类?

在学习包装类之前,我们要了解包装类用来干什么?
前面提过的Java 8大数据类型(整型:byte ,short , int , long ;浮点型: float ,double;布尔类型:boolean ;字符型: char )。

  • 在面向对象编程
  1. Java 中的包装类 (Wrapper Classes) 是为了解决基本数据类型(如 int, char, double 等)不能直接作为对象使用的问题。
  2. 为引入泛型和后续集合框架(Java数据结构) 打基础。比如列表,集合,映。Java中一切皆对象的理念,从设计的角度来看,对象的引用可以提供更多的灵活性和功能,比如可以内置更多的常量属性和便捷的方法
  3. 前面1提过,这里具体说一下:由于包装类提供了许多实用的方法和属性,用于操作和处理基本数据类型。比如,valueOf方法,Integer类提供了将字符串转换为整数的方法,以及获取整数的最大值、最小值等属性。
  4. 支持null值:基本数据类型不支持null值,但在某些情况下,我们可能需要表示一个变量没有值。可以通过使用包装类,将引用设置为null来表示这种情况。
  5. Java泛型不支持基本数据类型。

一、包装类的定义概念

在Java中,基本类型不是类,为了在泛型代码中可以支持基本类型,Java给每个基本类型都对应了一个包装类型。
包装类
int与char类型的包装类分别是Integer,Character。其余类型的包装类,类名是原基本数据类型关键字首字母大写。

包装类的使用

如果你不想关注包装类与基本数据类型内部的细节,你可以完全把包装类当成其基本数据类型使用。
包装类可以理解为升级版的基本数据类型,包装类与基本数据类型之间可以相互转换,且这种转换是自动的。

int a = 10;
Integer aObj = a;//等价

Integer bObj = 20;
int b = bObj; //等价

关于泛型:
假设你要设计一个整型数组列表,ArrayList<int>是错误的写法,<>是泛型的写法,<>内只能传类,而不能是基本数据类型。
var list = new ArrayList<Integer>(),改成包装类就可以了。

二、包装类之间的继承关系

Java 中的包装类位于 java.lang 包中,并且它们都继承自 java.lang.Number 类(除了 Boolean 和 Character)。
具体包装类查阅文档

java.lang.Object
    ├── java.lang.Number
    │     ├── java.lang.Byte
    │     ├── java.lang.Short
    │     ├── java.lang.Integer
    │     ├── java.lang.Long
    │     ├── java.lang.Float
    │     └── java.lang.Double
    ├── java.lang.Character
    └── java.lang.Boolean

简单说明Number类,它是一个抽象类,Number类是所有包装类的父类(除了 Boolean 和 Character)。
Number类提供了将包装类转换为基本数据类型的方法,如intValue()、doubleValue()等。这些方法是由子类实现,作用是将包装类转化成对应的基本数据类型。

三、装箱与拆箱

int 与 Integer怎么转换呢?

Integer integer = new Integer(1),对于类实例化对象,你可能比较熟悉了。
但事实上只需Integer integer = 1;Java底层设计,我们对于包装类不需要调用方法来手动转化,而是把它交给虚拟机操心。
先说明两个概念:

  1. 自动装箱:将基本数据类型转换为包装类。
  2. 自动拆箱:将包装类转换为基本数据类型。
    Java虚拟机在运行时,会自动将基本数据类型转换为对应的包装类,这个过程称为自动装箱。同样地,Java虚拟机也会自动将包装类转换为基本数据类型,这个过程称为自动拆箱。
    尝试一下手动装箱吧。
    基本数据类型转包装类,采用的valueOf静态方法方法,而不是构造器(该方法已不推荐使用)。
int x = 10;
Integer y = Integer.valueOf(x);

包装类转基本数据类型,采用intValue()方法。

Integer x = 10;
int y = x.intValue();
//int y = (int)x; // 也可以类型转换写。
使用过程中,手动装箱和拆箱带来不少的代码量,所以为了减少开发者的负担,java 提供了自动机制。
我们没必要手动装箱和拆箱,java 虚拟机会自动帮我们完成,所以只是了解一些JVM在这个过程实际上帮我们调用了这些方法。

## 包装类与基本数据类型的区别
你知道包装类是对象,基本数据类型是值。
但好像实际体验看包装类也可以完全充当基本数据类型啊。
```java
Integer a = 10;
Integer b = 10;
System.out.println(a == b); 

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

输出结果:

true
false

为什么会出现这种情况呢?
这是因为Java在处理包装类时,有一个缓存机制。对于-128到127之间的整数,Java会缓存这些整数对应的包装类对象,当创建一个在这个范围内的整数包装类对象时,Java会直接返回缓存中的对象,而不是创建一个新的对象。这就是为什么a和b是相等的,因为它们引用的是同一个对象。而对于1000,Java不会缓存这个值对应的包装类对象,所以c和d引用的是不同的对象,所以它们不相等。

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

// IntegerCache是Integer类的一个内部类,它定义了两个静态变量low和high,分别表示缓存中最小值(-128)和最大值(127)。
static final Integer[] cache;
// cache数组用于存储缓存中的包装类对象,数组长度为256,即缓存了-128到127之间的整数对应的包装类对象。这些对象在静态区创建好了,这个范围内的数只需返回缓存中的对象即可,而不在这个范围内的数则直接创建新的对象。否则则要直接new一个对象。
结论:包装类是对象,符合缓存区的int数据,会让它们引用一个同一个静态区的对象,否则则创建新的对象。这就是上面true和false的原因。

遇事不决翻源码文档·和问ChatGpt。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值