• 夯实Java基础(六)——包装类


    1、包装类简介

    我们都知道Java是面向对象编程语言,包含了8种基本数据类型,但是这8种基本数据类型并不支持面向对象的特征,它们既不是类,也不能调用方法。这在实际使用时存在很多的不便,比如int类型需要转换成字符串,为了解决这个不足。然后就出现了包装类,顾名思义,就是将这些基本数据类型封装在类中,并且提供丰富的方法来对数据进行操作。这样八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

    Java中的包装类提供了将基本数据类型转换为对象,以及将对象转换为基本数据类型的机制。

     

    其中Byte,Short,Integer,Float,Double,Long都属于Number子类。Character ,Boolean属于Object子类。它们的默认值都是NULL。

    2、基本数据类型、包装类、字符串之间的转换

    ①、基本数据类型转换为包装类(装箱):调用包装类的构造器

    //基本数据类型——>包装类:调用包装类的构造器
    @Test
    public void test1(){
        int num=10;
        Integer i1=new Integer(num);
        System.out.println("i1结果:"+i1);
        Integer i2=new Integer("10");
        System.out.println("i2结果:"+i2);
        //报错,必须是纯数字,java.lang.NumberFormatException: For input string: "10abc"
        //Integer i3=new Integer("10abc");
        //System.out.println(i3);
        Double d1=new Double(12.3);
        Double d2=new Double("12.3");
        System.out.println("d1结果:"+d1);
        System.out.println("d1结果:"+d2);
        Boolean b1=new Boolean(true);
        Boolean b2=new Boolean("TrUe");
        Boolean b3=new Boolean("TrUe123");
        System.out.println("b1结果:"+b1);
        System.out.println("b2结果:"+b2);
        System.out.println("b3结果:"+b3);
    }

    运行结果:

    从运行的结果来看,通过调用包装类构造器可以将基本数据类型转为包装类,但是传入的参数必须合法,否则就像Integer那样会报错。可以看见Boolean包装类传入的字符串是忽略大写的,这是因为构造器中调用了parseBoolean(String s)方法,然后这个方法内部又调用了String方法的equalsIgnoreCase(String anotherString)方法,所以传入字符串会忽略大小写。而且你传入的是非法字符串它并不会报错,只是返回了false,这里需要注意一下。

     ②、包装类转换为基本数据类型(拆箱):调用包装类的Xxx的xxxValue()方法

    //包装类——>基本数据类型:调用包装类的Xxx的xxxValue()方法
    @Test
    public void test2(){
        Integer integer = new Integer(10);
        int i=integer.intValue();
        System.out.println(i+1);
        Double aDouble = new Double(10.11);
        double d=aDouble.doubleValue();
        System.out.println(d+1);
        Boolean aBoolean = new Boolean(false);
        boolean b=aBoolean.booleanValue();
        System.out.println(b);
    }

    运行结果:

    包装类转换为基本数据类型是非常简单的,只需要调用正确的方法即可,其他的包装类也是同样的道理。

    你会发现前面两个点这样换来换去会非常的麻烦,其实从JDK5之后就变得非常简单了,这就要到后面介绍自动拆箱和自动装箱。

    ③、由于出现了自动拆箱和自动装箱,基本数据类型和包装类就可以看成一个整体。

    基本数据类型、包装类转换为字符串:调用String重载的valueOf(Xxx xxx)

    //基本数据类型、包装类->字符串:调用String重载的valueOf(Xxx xxx)
    @Test
    public void test3(){
        int num=10;
        //方式1:连接运算
        String str1=num+"";
        System.out.println("str1结果"+str1);
        //方式2:调用String的valueOf(Xxx xx)方法
        int num1=15;
        String str2=String.valueOf(num1);
        System.out.println("str2结果"+str2);
        Integer integer=new Integer(21);
        String str3=String.valueOf(integer);
        System.out.println("str3结果"+str3);
    
    }

    运行结果:

    ④、字符串转换为基本数据类型、包装类:调用包装类中的parseXxx()方法

    //字符串——>基本数据类型、包装类:调用包装类中的parseXxx()方法;
    @Test
    public void test5(){
        String str1="211";
        int num=Integer.parseInt(str1);
        System.out.println(num);
        //运行报错,ava.lang.NumberFormatException: For input string: "211abc"
        //String str2="211abc";
        //int num1=Integer.parseInt(str2);
        String str3="truetrue";
        boolean b=Boolean.parseBoolean(str3);
        System.out.println(b);
    }

    运行结果:211、false。

    无论怎样转换,数据的格式必须是正确的,否则就会报错,boolean特殊点,返回的是false。

    最后它们三者的转换可以详细归结为:

    1、基本数据类型与包装类之间转换:直接使用自动装箱和自动拆箱(后面会讲到,非常简单)。

    2、基本数据类型、包装类转换为字符串:调用String的valueOf(Xxx xxx)方法。

    3、字符串转换为基本数据类型、包装类:调用包装类的parseXxx()方法。

    另外包装类中还有丰富的方法可供大家调用,如需学习可以自行查看包装类的API。

    3、自动拆箱和自动装箱

    将基本数据类型变成包装类称为装箱,将包装类的类型变为基本数据类型称为拆箱。

    在JDK1.5之后,Java提供了自动装箱和自动拆箱功能。

    下面来看一下案例:

    @Test
    public void test6(){
        int i=21;
        Integer integer=i;//自动装箱
        int j=integer;//自动拆箱
        
        double d=21.11;
        Double aDouble=d;
        double e=aDouble;
    }

    由于出现了自动装箱和自动拆箱功能,所以基本数据类型和包装类之间的相互转换变得非常简单,再也不用去调用繁琐的方法了。

    但是也会出现一些特殊的情况,案例如下:

    @Test
    public void test7(){
        Integer a=127;
        Integer b=127;
        System.out.println(a == b);
    
        Integer c=128;
        Integer d=128;
        System.out.println(c == d);
    }

    运行结果:

    运行的结果肯定会有很大的疑问?同样是两个int型自动装箱为包装类进行比较,为什么127比较返回是true,而128比较则返回了false。这是为什么呢?这与Java的Integer类的设计有关,查看Integer类的源代码,如下所示。

        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.
                    }
                }
                //将127赋给high变量
                high = h;
                //定义长度为256的Integer数组
                cache = new Integer[(high - low) + 1];
                int j = low;
                //执行初始化,创建-128~127的Integer实例,并放入cache[]数组中
                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() {}
        }

    从上面代码可以看出,Integer类中定义了一个IntegerCache内部类,内部类中定义了一个静态常量的Integer cache [ ]数组,而这个数组存储了从-128~127之间的整数自动装箱成Integer实例,如果我们使用自动装箱的方式,给Integer包装类赋值时,范围在-128~127之间,就可以直接使用数组中的元素,因为-128~127之间的同一个整数自动装箱成Integer实例时,永远是引用cache数组的同一个数组元素。如果超出了这个范围,自动装箱需要再重新new对象,所以就出现了程序中的运行结果。

    4、小结

    1、包装类的默认值都是NULL。

    2、基本数据类型、包装类、字符串之间的转换可以归结为:

    • 基本数据类型与包装类之间转换:直接使用自动装箱和自动拆箱。
    • 基本数据类型、包装类转换为字符串:调用String的valueOf(Xxx xxx)方法。
    • 字符串转换为基本数据类型、包装类:调用包装类的parseXxx()方法。

    3、Integer类中默认存放值的范围是-128~127之间。

  • 相关阅读:
    tcp/ip ---IP路由选择
    tcp/ip --IP:网际协议
    tcp/ip ---以太网和IEEE 802封装
    tcp/ip ---链路层
    internet与Internet的区别
    TCP/IP ---封装与分用
    TCP/IP ---互联网的地址
    SpringMvc 系统启动时加载数据到内存中
    hadoop-17-hive数据库元数据查看
    hadoop-16-sqoop导入oracle数据
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/11218234.html
Copyright © 2020-2023  润新知