首页 > 其他 > 详细

基本数据类型和包装类

时间:2019-10-12 14:23:22      阅读:73      评论:0      收藏:0      [点我收藏+]

基本数据类型

Java基本数据按类型可以分为四大类:布尔型,整数型,浮点型,字符型,这四大类包含8中基本数据类型。

  • 布尔型:boolean
  • 整数型:byte、short、int、long
  • 浮点型:float、double
  • 字符型:char

8种基本类型取值如下:

数据类型 代表含义 默认值 取值 包装类
boolean 布尔型 false 0(false)/1(true) Boolean
byte 字节型 (byte)0 -128到127 Byte
char 字符型 ‘\u0000‘(空) ‘\u0000‘到‘\uFFFF‘ Character
short 短整数型 (short)0 -2^15到2^15 Short
int  整数型 0 -2^31到2^31-1 Integer
long 长整数型 0L -2^63到2^63-1 Long
float 单浮点型 0.0f 1.4e-45到3.4e+38 Float
double 双浮点型 0.0d 4.9e-324到1.798e+308 Double

 

 除char的包装类Character和int的包装类Integer之外,其他基本数据类型的包装类只需要首字母大写即可。包装类的作用和特点,本文下半部分详细讲解。

我们可以在代码中,查看某种类型的取值范围,代码如下:

    public static void main(String[] args) {
        // Byte 取值:-128 ~ 127
        System.out.println(String.format("Byte 取值: %d ~ %d", Byte.MIN_VALUE,Byte.MAX_VALUE));
        // Integer 取值: -2147483648 ~ 2147483647
        System.out.println(String.format("Integer 取值: %s ~ %s", Integer.MIN_VALUE,Integer.MAX_VALUE));
    }

 

包装类型

我们知道8种基本数据类型都有其对应的包装类,因为Java的设计思想是万物既对象,有很多时候我们需要以对象的形式操作器某项功能,比如说获取哈希值(hashcode)或获取类(getClass)等。

那包装类特性有哪些呢?

1.功能丰富

包装类本质上是一个对象,对象就包含属性和方法,比如hashCode、getClass、max、min等。

2.可定义泛型类型参数

包装类可以定义泛型,而基本类型不行。

比如使用Integer定义泛型,代码:

List<Integer> list = new ArrayList<>();

如果使用int定义就会报错,代码:

技术分享图片

3.序列化

因为包装类都实现了Serializable接口,所以包装类天然支持序列化和反序列化。比如Integer的类图如下:

技术分享图片

4.类型转换

包装类提供了类型转换的方法,可以很方便的实现类型之间的转换,比如Integer类型转换代码:

        String age = "18";
        int ageInt = Integer.parseInt(age) + 2;
        //输出结果:20
        System.out.println(ageInt);

5.高频区间的数据缓存

此特性为包装类很重要的用途之一,用于高频区间的数据缓存,以Integer为例来说,在数值区间为-128~127时,会直接复用已有对象,在这区间之外的数字才会在堆上产生。

我们使用 == 对 Integer 进行验证,代码如下:

    public static void main(String[] args) {
        // Integer 高频区缓存范围 -128 ~ 127
        Integer num1 = 127;
        Integer num2 = 127;
        // Integer 取值127 == 结果为 true (值127 num1==num2 =>true)
        System.out.println("值127 num1==num2 =>" + (num1 == num2));

        Integer num3 = 128;
        Integer num4 = 128;
        // Integer 取值128 == 结果为 false (值128 num3==num4 =>false)
        System.out.println("值128 num3==num4 =>" + (num3 == num4));
    }

从上面的代码很明显可以看出,Integer为127时复用了已有的对象,当值为128时,重新在堆上生成了新对象。

为什么会产生高频区域数据缓存呢?我们查看源码就能发现“线索”,源码版本 JDK8,源码如下:

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

由此可见,高频区域的数值会直接使用已有对象,非高频区域的数值会重新new一个新的对象。

各包装类高频区域的取值范围:

  • Boolean: 使用静态final定义,就会返回静态值
  • Byte:缓冲区 -128~127
  • Short:缓冲区 -128~127
  • Character:缓冲区 0~127
  • Long:缓冲区 -128~127
  • Integer:缓冲区 -128~127

包装类的注意事项

  • int默认值是0,而Integer的默认值是null
  • 推荐所有包装类对象之间的值比较实用equals()方法,因为包装类的非高频去数据会在堆上产生,而高频区又会复用已有对象,这样会导致同样的代码,因为取值不同,而产生两种截然不同的结果。代码示例:
    public static void main(String[] args) {
            // Integer 高频区缓存范围 -128 ~ 127
            Integer num1 = 127;
            Integer num2 = 127;
            // Integer 取值127 == 结果为 true (值127 num1==num2 =>true)
            System.out.println("值127 num1==num2 =>" + (num1 == num2));
    
            Integer num3 = 128;
            Integer num4 = 128;
            // Integer 取值128 == 结果为 false (值128 num3==num4 =>false)
            System.out.println("值128 num3==num4 =>" + (num3 == num4));
            // Integer 取值128 equals 结果为 true (值128 num3.equals(num4) =>true)
            System.out.println("值128 num3.equals(num4) =>" + (num3.equals(num4)));
        }
  • Float 和 Double不会有缓存,其他包装类都有缓存。
  • Integer是唯一一个可以修改缓存范围的包装类,在VM options加入参数:
    -XX:AutoBoxCacheMax=666 即修改缓存最大值为666。

    示例代码如下:

        public static void main(String[] args) {
            Integer num1 = 128;
            Integer num2 = 128;
            System.out.println("值为-128 =>" + (num1 == num2));
            Integer num3 = 666;
            Integer num4 = 666;
            System.out.println("值666 num3==num4 =>" + (num3 == num4));
            Integer num5 = 667;
            Integer num6 = 667;
            System.out.println("值为667 =>" + (num5 == num6));
        }

    执行结果如下:

    值为-128 =>true
    值为666 =>true
    值为667 =>false

    由此可见将Integer最大缓存修改为666之后,667不会被缓存,而-128~666之间的数都被缓存了。

 

基本数据类型和包装类

原文:https://www.cnblogs.com/Night-Watch/p/11661188.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!