zoukankan      html  css  js  c++  java
  • 夯实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之间。

  • 相关阅读:
    正经学C#_循环[do while,while,for]:[c#入门经典]
    Vs 控件错位 右侧资源管理器文件夹点击也不管用,显示异常
    asp.net core 获取当前请求的url
    在实体对象中访问导航属性里的属性值出现异常“There is already an open DataReader associated with this Command which must be
    用orchard core和asp.net core 3.0 快速搭建博客,解决iis 部署https无法登录后台问题
    System.Data.Entity.Core.EntityCommandExecution The data reader is incompatible with the specified
    初探Java设计模式3:行为型模式(策略,观察者等)
    MySQL教程77-CROSS JOIN 交叉连接
    MySQL教程76-HAVING 过滤分组
    MySQL教程75-使用GROUP BY分组查询
  • 原文地址:https://www.cnblogs.com/tanghaorong/p/11218234.html
Copyright © 2011-2022 走看看