【学习笔记】包装类

包装类

什么是包装类?

  • 基本数据类型所对应的引用数据类型

  • 基本数据类型中都存放在栈中,引用类型数据在堆中存放,它们的地址存在栈中

  • Object 可同一所有数据,包装类的默认值是null

包装类对应

image-20220720170610426

 

  • 把基本类型的值包装在一个对象中,那么这个数据就放在堆空间中了

 

装箱和拆箱

  • 装箱:把基本类型转换成引用类型

    • 通过构造方法实现装箱

    • 或者调用valueOf()

  • 拆箱:把引用类型转换成基本类型

    • 六个包装类Byte,Double,Float,Integer,Long,Short 都继承 Number 类

    • Number 类 中提供了把引用类型转换成基本类型的方法 如:byteValue() intValue() 等

 

代码实现:

package com.packageClass;
​
public class demo01 {
​
    public static void main(String[] args) {
        int num = 23;
        //装箱
        System.out.println("装箱");
        Integer integer1 = new Integer(num);
        Integer integer2 = Integer.valueOf(num);
        System.out.println(integer1);
        System.out.println(integer2);
        System.out.println("====================");
        //拆箱
        System.out.println("拆箱");
        Integer integer3 = new Integer(100);
        int num1 = integer3.intValue();
        System.out.println(num1);
    }
}

image-20220720172947070

 

  • JDK 1.5之后 ,java提供了自动装箱和拆箱

 //JDK 1.5之后 ,java提供了自动装箱和拆箱
        int num3 = 200;
        //自动装箱
        System.out.println("自动装箱");
        Integer integer4 = num3;
        System.out.println(integer4);
        System.out.println("====================");
        //自动拆箱
        System.out.println("自动拆箱");
        int num4 = integer4;
        System.out.println(num4);

image-20220720173123893

在java文件中,虽然实现了自动装箱和拆箱,但在字节码文件中,依然是使用valueOf() 方法实现装箱

装箱和拆箱的作用?

Java是一种完全面向对象的语言。因此,包括数字、字符、日期、布尔值等等在内的一切,都是对象。似乎只需要一种方式来对待这些对象就可以了。 对于CPU来说,处理一个完整的对象,需要很多的指令,对于内存来说,又需要很多的内存。如果连整数都是对象,那么性能自然很低。 于是创造了这样一种机制,使得这些基本类型在一般的编程中被当作非对象的简单类型处理,在另一些场合,又允许它们被视作是一个对象。 这就是装箱和拆箱。 作用:为了保证通用性和提高系统性能 一种最普通的场景是调用一个包含类型为Object的参数的函数(方法),该Object可支持任意 类型,以便通用。当你需要将一个值类型传入容器时,就需要装箱了。 另一种的用法,就是一个泛型 的容器,同样是为了保证通用,而将元素定义为Object类型的,将值类型的值加入该容器时,需要装箱。

 

基本类型和字符串之间的转换

  • 基本类型转换成字符串

 //1基本类型转换成字符串
        int num1 = 100;
        //1.1 使用 + 号 将其与字符串连接起来
       String s1 = num1 + "";
        //1.2使用Integer中的toString() 方法
        String s2 = Integer.toString(num1);
            //还可以使用toString的重载方法,将数值转换成不同进制
        String s3 = Integer.toString(num1,16);   //将num1 转换成16进制
  • 字符串转换成基本类型

     //2字符串转换成基本类型
            String str = "150";
            //使用Integer中的方法parseXXX()
            int num2 = Integer.parseInt(str);

    注意:使用parseInt() 方法时,字符串中的内容只能是数字,不能出现其他字符

    否则会报错

    image-20220720175631518

NumberFormatException:数字格式化异常

 

  • boolean 字符串类型转换成基本类型

    • “true” ----> true 非“true” ------> false

String str2 = "true";
String str3 = "trues";
boolean flag1 = Boolean.parseBoolean(str2);
boolean flag2 = Boolean.parseBoolean(str3);
System.out.println(flag2);

image-20220720180127403

 

整数缓冲区

  • java预先创建了256个常用的整数包装类型对象 -128~127

 

通过面试题来理解

package com.packageClass;
​
public class demo02 {
    public static void main(String[] args) {
        Integer integer1 = new Integer(100);
        Integer integer2 = new Integer(100);
        System.out.println(integer1 == integer2);
    }
}
​

image-20220720183128608

结果为false,它们都是引用类型,这个比较的是它们的地址是否相同,结果是不同的

继续向下看:

package com.packageClass;
​
public class demo02 {
    public static void main(String[] args) {
        Integer integer1 = new Integer(100);
        Integer integer2 = new Integer(100);
        System.out.println(integer1 == integer2);
​
        int num = 100;
        Integer integer3 = num; //自动装箱
        Integer integer4 = num;
        System.out.println(integer3 == integer4);
​
        int num1 = 200;
        Integer integer5 = num1; //自动装箱
        Integer integer6 = num1;
        System.out.println(integer5 == integer6);
    }
}
​

image-20220720185731453

 

出现这种结果的原因是:自动装箱是用调用valueOf() 来实现的

我们来反编译一下 class文件

image-20220720191327157

所以说这些结果是因为 valueOf()

我们来查看一下 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);
}

image-20220720192213326

image-20220720192705402

cache 是 Integer 类型的 数组,长度是 (high - low) + 1 ========256

所以cache中有 256 个数组元素

并且通过 for 循环 给 cache 初始化

 

我们在回到 valueOf() 方法

image-20220720192846709

如果参数 i 大于 -128 小于 127 ,我们就从cache数组中取 这个对象

我们上面给的 integer3,integer4 的值为100,在上面的范围之内,所以返回的是Integer缓冲区cache数组中的对象

从内存中看

image-20220720194001952

我们自动装箱时,在cache数组中找 integer3,integer4 所对应的数值 即 100 找到了就把这个100的地址给 integer3,integer4 所以它们的地址是相等的

如果像 integer5,integer6 没有找到 它们所对应的 200数值 则 return new Integer() 在堆中开辟空间,所以integer5,integer6 它们两个开辟了两块空间,所以它们的地址不相同

 

这样设计的原因是:在开发过程中,这些数字用的比较多,所以我们把它们创建为对象从而进行复用,可以节省内存的消耗

posted @   GrowthRoad  阅读(129)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示