Java 8增强的包装类

本文介绍了Java中的包装类及其在Java 8中的自动装箱和自动拆箱特性。从JDK1.5开始,Java提供了自动装箱(Autoboxing)和自动拆箱(AutoUnboxing)功能,简化了基本类型与对象之间的转换。通过包装类,开发者可以将基本变量近似地当作对象使用。此外,包装类还支持基本类型与字符串之间的转换。在比较包装类实例时,需要注意-128到127之间的整数会被缓存,导致特定情况下的相等性判断。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Java是面向对象的编程语言,但它也包含了8种基本数据类型,这8种基本数据类型不支持面向对象的编程机制,基本数据类型也不具备“对象”的特性:没有成员变量、方法可以被调用。Java之所以提供8种数据类型,主要是为了照顾程序员的传统习惯。

这8种基本数据类型带来了一定的方便些,例如可以进行简单、有效的常规数据处理。但在某些时候,基本数据类型会有一些制约,例如所有引用类型的变量都继承了Object类,都可以当成Object类型变量使用。但基本数据类型的变量就不可以

为了解决8种基本数据类型的变量不能当成Object类型变量使用的问题,Java提供了包装类(Wrapper Class)的概念,为8种基本数据类型分别定义了相同的引用类型,并称之为基本数据类型的包装类。

            基本数据类型和包装类对应关系
基本数据类型包装类
byteByte
shortShort
intInteger
longLong
charCharacter
floatFloat
doubleDouble
booleanBoolean

在JDK1.5以前,把基本数据类型变量变成包装类实例需要通过对应包装类的构造器实现。

但从JDK1.5开始,JDK提供了自动装箱(Autoboxing)和自动拆箱(AutoUnboxing)功能。
所谓自动装箱,就是可以把一个基本类型变量直接赋给对应的包装变量,或者赋给Object变量(Object是所有类的父类,子类对象可以直接赋给父类变量);自动拆箱则与之相反,允许直接把包装类对象直接赋给一个对应的基本类型变量

下面程序示范自动装箱和自动拆箱

public class AutoBoxingUnboxing
{
    public static void main(String[] args)
    {
        //直接把一个基本类型变量赋给Integer对象
        Integer inObj = 5;
        //直接把一个boolean类型变量赋给一个Object类型的变量
        Object boolObj = true;
        //直接把一个Integer对象赋给int类型变量
        if(boolObj instanceof Boolean)
        {
            //先把Object对象强制类型转换为Boolean类型
            //再赋给boolean变量
            boolean b = (Boolean)boolObj;
            System.out.println(b);
        }
    }
}

当JDK提供了自动装箱和自动拆箱功能后,大大简化了基本类型变量和包装类对象之间的转换过程。值得指出的是,进行自动拆箱和自动拆箱必须注意类型匹配。
例如Integer只能自动拆箱成int类型变量,不要试图拆箱成boolean类型变量;与之类似的是,int类型变量只能自动装箱成Integer对象(即使赋给Object类型变量,也只是利用了Java类型的向上自动转型特性),不要试图装箱成boolean对象。

借助包装类的帮助,再加上JDK1.5提供的自动装箱、自动拆箱功能,开发者可以把基本变量“近似”地当成对象使用(所有装箱、拆箱过程都是由系统自动完成,无须程序员理会)。

除此之外,包装类还可实现基本类型变量和字符串之间的转换。把字符串类型的值转换为基本类型的值有两种方式。
利用包装类提供的parseXxx(String s)静态方法(除了Character之外的所有包装类都提供了该方法)

利用包装类提供的XXX(String s)构造器

String类提供了多个重载valueOf()方法,用于将基本类型转换成字符串,下面程序示范了这种转换关系。

public class Primitive2String
{
    public static void main(String[] args)
    {
        String intStr = "123";
        //把一个特定字符串转换成int变量
        int it1 = Integer.parseInt(intStr);
        int it2 = new Integer(intStr);
        System.out.println(it2);
        String floatStr = "4.56";
        //把一个特定字符串转换成float变量
        float ft1 = Float.parseFloat(floatStr);
        float ft2 = new Float(floatStr);
        System.out.println("ft2");
        //把一个float变量转换成String变量
        String ftStr = String.valueOf(2.345f);
        System.out.println(ftStr);
        //把一个double变量转换成String变量
        String dbStr = String.valueOf(3.344);
        System.out.println(dbStr);
        //把一个boolean变量转换成String变量
        String boolStr = String.valueOf(true);
        System.out.println(boolStr.toUpperCase());
    }
}

通过上面的程序可以看出基本类型和字符串之间的转换关系。
如果希望把基本类型变量转换成字符串,还有一种更简单的方法:把基本类型和 “” 进行连接运算,系统会自动把基本类型变量转换成字符串,如下面代码:

//inStr的值为"5"
String intStr = 5 + "";

虽然包装类的变量时引用数据类型,但包装类的实例可以与数值类型的值进行比较,这种比较时直接取出包装类的实例所包装的数值来进行比较的。

Integer a = new Integer(6);
//输出true
System.out.println("6的包装类实例是否大于5.0" + (a > 5.0));

两个包装类的实例进行比较的情况比较复杂,因为包装类的实例实际上是引用类型,只有两个包装类引用指向同一个对象时才会返回true。下面代码示范了这种效果。

System.out.println("比较两个包装类实例是否相等:" + (new Integer(2) == new Integer(2)));

但JDK1.5以后支持自动装箱,自动装箱就是可以把一个基本类型值赋给包装类实例,在这种情况下可能会出现一些特别的情形。

Integer ina = 2;
Integer inb = 2;
//输出true
System.out.println("两个2自动装箱后是否相等:" + (ina == inb));
Integer biga = 128;
Integer bigb = 128;
//输出false
System.out.println("两个128自动装箱后是否相等"+(biga == bigb));

上面程序让人费解,同样是两个int类型的数值自动装箱成Integer实例后,如果是两个2自动装箱后就相等;如果是两个128自动装箱后就不相等,这是为什么呢?这与Java的Integer类的设计有关,查看Java系统的java.lang.Integer类的源代码,如下所示。

//定义一个长度为256的Integershuzu1
static final Integer[] cache = new Integer[-(-128)+127-1];
staic {
    //执行初始化,创建-128~127的Integer实例,并放入cachr数组中
    for(int i = 0;i < cache.length;i++)
        cache[i] = new Integer(i-128);
}

从上面代码可以看出,系统把一个-128~127之间的整数自动装箱成Integer实例,并放入了一个名为cache的数组中缓存起来。如果以后把也-128~127的整数自动装箱成Integer实例时,实际上是直接指向对应的数组元素,因此-128~127之间的同一个整数自动装箱成Integer实例时,永远是引用cache数组的同一个数组元素;但是将一个不在-128~127范围内的整数自动装箱成Integer实例时,系统总是重新创建一个Integer实例,所以出现程序中的运行结果。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值