欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA基本数据类型及其对应的包装类

程序员文章站 2022-04-04 20:06:43
...

一、JAVA中的八种基本类型

1、数字类型(6种)

  ①byte:

    占的位数:byte数据类型占八位;

    最小值为:-128(-2^7);

    最大值为:127(2^7-1);

    默认值为:0;

    作用:byte数据类型主要用于在大型数组中节约空间,用来代替整型,因为byte类型只占八位,占用的空间只有int型的1/4;

②short:

    占的位数:short数据类型占16位;

    最小值为:-32768(-2^15);

    最大值为:32767(2^15 - 1);

    默认值为:0;

    作用:像byte类型一样节约空间,当大型数组中的元素值大小超过了byte类型却小于int类型,则用short类型存储,short类型占用的空间只有int类型的二分之一;

③int:

    占的位数:int数据类型占32位;

    最小值为:-2,147,483,648(-2^31);

    最大值为:2,147,483,647(2^31 - 1);

    默认值为:0;

    作用:一般整型变量默认为int型;

④long:

    占的位数:long数据类型占64位;

    最小值为:-9,223,372,036,854,775,808(-2^63);

    最大值为:9,223,372,036,854,775,807(2^63 -1);

    默认值为:0L;

    作用:用于存储数值超过int类型范围的值;

⑤float:

    占的位数:单精度,占32位;

    最小值为:1.4E - 45;

    最大值为:3.4028235E38;

    默认值为:0.0f;

    作用:用于存储大型浮点数组的时候可节省内存空间;

⑥double:

    占的位数:双精度,占64位;

    最小值为:4.9E-324;

    最大值为:1.7976931348623157E308;

    默认值为:0.0d;

    作用:浮点数默认类型为double类型;

注:①float和double类型不能用来表示精确的值,如货币;②为long类型的变量赋值时要在值后面加上'L',为float类型的变量赋值时要在值后面加上'f'。

数字类型取值范围的计算方法:参考博客https://blog.csdn.net/u011601165/article/details/51658910/

2、字符类型(1种)

char:

    占的位数:char类型是一个单一的 16 位 Unicode 字符;

    最小值: \u0000(即为0);

    最大值: \uffff(即为65,535);

    作用:char数据类型可以存储任何字符;

3、布尔型(1种)

boolean:

     说明:只有两个取值:true 和 false;

     默认值:false;

     作用:作为一种标志来记录 true/false 情况;

     占的位数:参考该博客https://www.jianshu.com/p/2f663dc820d0

4、其他

JAVA基本数据类型及其对应的包装类

二、类型转换

1、转换的规则

    整型、实型(常量)、字符型数据可以混合运算。运算时,不同的数据类型先转换为同一数据类型,然后进行运算。

    数据类型转换必须满足如下规则:

    ①不能对boolean数据类型进行转换;

    ②不能把对象类型转换为不相关类对象;

    ③在把容量大的类型转换为容量下的类型时,必须用强制类型转换;

    ④转换过程中可能会导致溢出或损失精度,如:int i = 128,byte b = (byte)i;这里b = -128(溢出);

    ⑤浮点数到整数的转换是舍去小数为,并不是四舍五入,如:float f = 3.7f,int i = (int)f;这里i = 3。

2、自动类型转换

需要满足的条件:转换前的类型所占的位数小于转换后的类型所占的位数,例如:short类型占16位,就可以自动转换成32为的int型,代码如下:

JAVA基本数据类型及其对应的包装类

3、强制类型转换

需要满足的条件:①转换的数据类型必须是兼容的;②格式:(type)value,type是要强制类型转换后的数据类型,代码如下:

JAVA基本数据类型及其对应的包装类

4、隐含类型转换

①整数的默认类型是int型;

②浮点数默认是double型,但是定义并初始化float类型变量的时候,值后面必须跟上F或者f。

三、基本类型对应的包装类

1、概述

  虽然 Java 语言是典型的面向对象编程语言,但其中的八种基本数据类型并不支持面向对象编程,基本类型的数据不具备“对象”的特性——不携带属性、没有方法可调用。 沿用它们只是为了迎合人类根深蒂固的习惯,并的确能简单、有效地进行常规数据处理。
  这种借助于非面向对象技术的做法有时也会带来不便,比如引用类型数据均继承了 Object 类的特性,要转换为 String 类型(经常有这种需要)时只要简单调用 Object 类中定义的toString()即可,而基本数据类型转换为 String 类型则要麻烦得多。为解决此类问题 ,Java为每种基本数据类型分别设计了对应的类,称之为包装类(Wrapper Classes),也有教材称为外覆类或数据类型类。

   基本数据类型对应的包装类如下图:

JAVA基本数据类型及其对应的包装类

2、装箱和拆箱

2.1、什么是装箱和拆箱?

   前面已经提到了,JAVA为每一个基本数据类型都提供了一个包装器类,在JAVA SE5之前,如果要生成一个数值为10的Integer对象,需要这么做:

Integer integer =  new Integer(10);

而在JAVA SE5开始就提供了自动装箱功能,如果要生成数值为10的Integer对象,只需要像下面这样做就行了:

Integer integer = 10;

这样写会触发自动装箱,能直接根据数值就能创建对应的Integer对象,而不用new操作。

那么拆箱是怎么样的呢?只需要像下面这样做就行了:

Integer integer = 5;//装箱
int i = integer;//拆箱

简而言之,装箱就是基本数据类型转换为包装器类型,拆箱就是包装器类型转换基本类型。

2.2、装箱和拆箱的过程是什么?

  通过上面的介绍,知道了什么是装箱何拆箱。不过装箱和拆箱的具体过程是什么呢?其实装箱和拆箱是调用了两个函数来实现的,下面通过一段代码来说明:

public class Main {

       public static void main(String[] args) {
    	     Integer integer = 5;
    	     int i = integer;	   
       }
}

反编译这段代码生成的class文件:

JAVA基本数据类型及其对应的包装类

从反编译的结果来看,装箱的时候调用了Integer.valueOf(int i)这个函数,拆箱的时候调用了Integer.intValue()这个函数。

总的来说,装箱的时候是调用的包装器的valueOf这个函数,拆箱的时候调用的是包装器的xxxValue这个函数(xxx是包装器对应的基本数据类型)。

2.3、装箱和拆箱关键源码分析

      通过上面的介绍,我们知道了装箱和拆箱关键在于valueOf和xxxValue这两个函数,xxxValue这个函数没有什么值得注意的,就是把包装器中的值装换为对应的基本数据类型。而valueOf这个函数在不同的包装器中,实现方法有很大的区别。

      下面,先介绍在Integer包装器类中,该方法是怎么实现的,源码如下:

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

        static {
            final int low = -128;

            // high value may be configured by property
            int h = 127;
            if (integerCacheHighPropValue != null) {
                // Use Long.decode here to avoid invoking methods that
                // require Integer's autoboxing cache to be initialized
                int i = Long.decode(integerCacheHighPropValue).intValue();
                i = Math.max(i, 127);
                // Maximum array size is Integer.MAX_VALUE
                h = Math.min(i, Integer.MAX_VALUE - -low);
            }
            high = h;

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

        private IntegerCache() {}
    }

从上面的源码可以知道,通过valueOf创建Integer对象的时候,如果数值在区间[-128,127],那么便返回指向IntegerCache.cache数组中已经存在的对象的引用;否则创建一个新的Integer对象。简而言之,创建Integer包装器时,有一个数值在[-128,127]的缓冲池。当创建的对象数值在[-128,127]之间时,那么不需要再在内存中开辟一个空间存储,只需要将当前对象的引用指向该缓冲池中对应的对象,这样效率上得到了提高,资源也没有浪费。、

    当然,这是Integer包装器类的value函数,其他的包装器不是这样,有兴趣的可以自己查看源码,这里不一 一详解。

相关标签: 学习