Java常用类:包装类

本文详细介绍了Java中的包装类,包括它们的作用、分类和继承体系。重点讲解了装箱和拆箱的概念,以及基本数据类型与引用类型、字符串之间的转换方式。同时,还探讨了Integer缓冲区的原理,展示了如何利用valueOf()方法提高程序效率。
摘要由CSDN通过智能技术生成


包装类概述

什么是包装类

一般地,当需要使用数字的时候,我们通常使用内置数据类型,如:byte、int、long、double 等。

例如:

int a = 5000;
float b = 13.65f;
byte c = 0x4a;

然而,在实际开发过程中,我们经常会遇到需要使用对象,而不是内置数据类型的情形。为了解决这个问题,Java 语言为每一个内置数据类型提供了对应的包装类。

简单来说,包装类就是八个基本数据类型所对应的引用数据类型

包装类的分类

在这里插入图片描述

包装类的继承体系

Integer、Long、Byte、Double、Float、Short都是抽象类 Number 的子类。

Boolean、Character则直接继承 Object 类。

在这里插入图片描述

装箱和拆箱

概述

装箱: 基本数据类型转为引用类型(将栈中的数据包装成堆中的数据)

拆箱: 引用类型转为基本数据类型(将堆中的数据拆出成栈中的数据)

举例

一个锚点

package com.ibelifly.commonclass.wrapperclass;

public class Test1 {
    public static void main(String[] args) {
        //装箱:基本数据类型转为引用类型
        int num1=100;
        Integer i1=new Integer(num1); //方法1
        Integer i2=Integer.valueOf(num1); //方法2
        System.out.println("装箱操作:");
        System.out.println(i1);
        System.out.println(i2);
        //拆箱:引用类型转为基本数据类型
        Integer i3=new Integer(100);
        int num2=i3.intValue();
        System.out.println("拆箱操作:");
        System.out.println(num2);
    }
}

在这里插入图片描述

上述实现装箱、拆箱的操作,出现在JDK1.5之前,在JDK1.5之后,Java能够实现自动装箱、拆箱操作。我们只需要如下编写代码:

package com.ibelifly.commonclass.wrapperclass;

public class Test2 {
    public static void main(String[] args) {
        //自动装箱
        Integer i=100;
        System.out.println(i);
        //自动拆箱
        int num=i;
        System.out.println(num);
    }
}

在这里插入图片描述

基本数据类型与引用类型之间的转换

引用类型——>基本数据类型

Integer、Long、Byte、Double、Float、Short类的父类(Number类)中,提供了6种方法实现引用类型向基本数据类型的转换:

方法功能
byteValue()将 Byte 对象转换为 byte 数据类型的值并返回
doubleValue()将 Double 对象转换为 double 数据类型的值并返回
floatValue()将 Float 对象转换为 float 数据类型的值并返回
intValue()将 Integer 对象转换为 int 数据类型的值并返回
longValue()将 Long 对象转换为 long 数据类型的值并返回
shortValue()将 Short 对象转换为 short 数据类型的值并返回

Boolean类和Character类中分别提供了方法实现引用类型向基本数据类型的转换:

方法功能
booleanValue()将 Boolean 对象转换为 boolean 数据类型的值并返回
charValue()将 Character 对象转换为 char 数据类型的值并返回

小结:

xxxValue()将包装类对象转换为对应的 xxx 数据类型的值并返回

基本数据类型——>引用类型

有两种方法:

  1. 通过各包装类的构造方法转化:

    方法功能
    Byte(byte value)构造一个新分配的 Byte 对象,该对象表示指定的 byte 值
    Double(double value)构造一个新分配的 Double 对象,该对象表示指定的 double 值
    Float(double value)构造一个新分配的 Float 对象,该对象表示指定的 float 值
    Integer(int value)构造一个新分配的 Integer 对象,该对象表示指定的 int 值
    Long(long value)构造一个新分配的 Long 对象,该对象表示指定的 long 值
    Short(short value)构造一个新分配的 Short 对象,该对象表示指定的 short 值
    Boolean(boolean value)构造一个新分配的 Boolean 对象,该对象表示指定的 boolean 值
    Character(char value)构造一个新分配的 Character 对象,该对象表示指定的 char 值

    小结:

    xxx(yyy value)构造一个新分配的 xxx 对象,该对象表示指定的 yyy 值(xxx为yyy对应的包装类)
  2. 通过 valueOf() 方法转化:

    每个包装类都有对应的valueOf()方法。

    valueOf(xxx value)返回一个包装类对象对应的 xxx 数据类型

举例

点击跳转到 - 举例

基本数据类型与字符串之间的转换

基本数据类型——>字符串

有多种方法,例如以下三种:

  1. 使用+号实现

    package com.ibelifly.commonclass.wrapperclass;
    
    public class Test3 {
        public static void main(String[] args) {
            int num1=20;
            int num2=21;
            String s1=num1+"";
            String s2=num1+""+num2;
            System.out.println(s1);
            System.out.println(s2);
        }
    }
    

    在这里插入图片描述

  2. 使用包装类中的toString(int i)方法

    package com.ibelifly.commonclass.wrapperclass;
    
    public class Test4 {
        public static void main(String[] args) {
            int num=20;
            String s=Integer.toString(num);
            System.out.println(s);
        }
    }
    

    在这里插入图片描述

  3. 使用包装类中的toString(int i,int radix)方法

    radix为你想要的进制数

    package com.ibelifly.commonclass.wrapperclass;
    
    public class Test4 {
        public static void main(String[] args) {
            int num=15;
            String s=Integer.toString(num,16);
            System.out.println(s);
        }
    }
    

    在这里插入图片描述

字符串——>基本数据类型

使用包装类中的parseXXX()方法,XXX为包装类对应的基本数据类型:

package com.ibelifly.commonclass.wrapperclass;

public class Test5 {
    public static void main(String[] args) {
        String s="150";
        int i=Integer.parseInt(s);
        System.out.println(i);
    }
}

在这里插入图片描述

注意:

  1. 定义字符串时,字符串中不能出现非数字的符号,否则会抛出数字格式化异常

  2. boolean字符串形式转换成基本数据类型时,“true”——>true,非“true”——>false:

    package com.ibelifly.commonclass.wrapperclass;
    
    public class Test6 {
        public static void main(String[] args) {
            String s1="true";
            String s2="tree";
            boolean b1=Boolean.parseBoolean(s1);
            boolean b2=Boolean.parseBoolean(s2);
            System.out.println(b1);
            System.out.println(b2);
        }
    }
    

    在这里插入图片描述

Integer缓冲区

要理解这一概念,我们首先来看这样一段代码:

package com.ibelifly.commonclass.wrapperclass;

public class Test8 {
    public static void main(String[] args) {
        Integer i1=new Integer(100);
        Integer i2=new Integer(100);
        System.out.println(i1==i2);
    }
}

在这里插入图片描述

它的输出结果为false,我们并不意外。因为i1i2分别指向了两个不同对象,==的作用是判断两个引用类型的内存地址是否相等,于是输出结果自然成了false

那么下面这一段代码呢?

package com.ibelifly.commonclass.wrapperclass;

public class Test8 {
    public static void main(String[] args) {
        Integer i3=100;
        Integer i4=100;
        System.out.println(i3==i4);
    }
}

在这里插入图片描述

为什么会输出true呢?我们先查看这段程序的反编译代码:

// Decompiled by Jad v1.5.8e2. Copyright 2001 Pavel Kouznetsov.
// Jad home page: http://kpdus.tripod.com/jad.html
// Decompiler options: packimports(3) fieldsfirst ansi space 
// Source File Name:   Test8.java

package com.ibelifly.commonclass.wrapperclass;

import java.io.PrintStream;

public class Test8
{

	public Test8()
	{
	}

	public static void main(String args[])
	{
		Integer i3 = Integer.valueOf(100);
		Integer i4 = Integer.valueOf(100);
		System.out.println(i3 == i4);
	}
}

我们发现,Java在自动装箱的过程中调用了valueOf()方法,所以我们查看一下valueOf()方法的源码,截取其中一段如下:

private static class IntegerCache {
    static final int low = -128;
    static final int high;
    static final Integer cache[];

    static {
        // high value may be configured by property
        int h = 127;
        String integerCacheHighPropValue =
            sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
        if (integerCacheHighPropValue != null) {
            try {
                int i = parseInt(integerCacheHighPropValue);
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            } catch( NumberFormatException nfe) {
                // If the property cannot be parsed into an int, ignore it.
            }
        }
        high = h;

        cache = new Integer[(high - low) + 1];
        int j = low;
        for(int k = 0; k < cache.length; k++)
            cache[k] = new Integer(j++);

        // range [-128, 127] must be interned (JLS7 5.1.7)
        assert IntegerCache.high >= 127;
    }

    private IntegerCache() {}
}

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

分析源码:

valueOf()方法中,有一个Integer缓冲区,在缓冲区中定义了一个cache数组并在堆中创建该数组,cache数组中预先存储了[-128,127]范围内的256个整数,当调用valueOf()方法时,若参数i在[-128,127]之间,则返回数组内预先存储好的数字,否则会返回一个新创建的Integer对象。

由上述分析可知,当我们给i3i4传值时,两次传入的整数都为100,而100在[-128,127]之间,所以两次都返回cache数组内的数字100,并将数字100的地址赋给i3i4,并没有创建新的Integer对象,故i3i4指向同一地址,输出为true

至此,我们可以推测,将[-128,127]范围之外的两个相同数字赋给不同变量时,Java会自动调用valueOf()方法,为两个变量创建两个新的对象,故两个变量所指向的地址是不相同的。我们来验证一下:

package com.ibelifly.commonclass.wrapperclass;

public class Test8 {
    public static void main(String[] args) {
        Integer i5=200;
        Integer i6=200;
        System.out.println(i5==i6);
    }
}

在这里插入图片描述

结论成立。

小结:

Integer缓冲区: Java在Integer缓冲区中预先创建了256个常用的整数包装类对象。

作用: 对已创建的对象进行复用,提高程序的运行速度。


参考视频:https://www.bilibili.com/video/BV1vt4y197nY?p=16

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值