java基本类型介绍

java中,基本数据类型一共有8种,详细信息如下表:

类型 大小 范围 默认值
byte 8 -128 - 127 0
short 16 -32768 - 32768 0
int 32 -2147483648-2147483648 0
long 64 -9233372036854477808-9233372036854477808 0
float 32 -3.40292347E+38-3.40292347E+38 0.0f
double 64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d
char 16 \u0000 - u\ffff \u0000
boolean 16 true/false false

Java语言是一种面向对象的语言,但是Java中的基本数据类型却是不面向对象的,这在实际使用时存在很多的不便,为了解决这个不足,设计者将每个基本数据类型单独封装成一个类,这八个和基本数据类型对应的类统称为包装类(Wrapper Class)。

1.什么是自动拆箱与自动装箱

自动装箱:把基本类型用它们对应的包装类包装起来,使它们具有对象的特质,可以调用所对应的包装类所定义的方法,比如toString()等。

举个例子:

   Integer i0 = new Integer(0);
Integer i1 = 2;
Integer i1_ = Integer.valueOf(2);

上面的三行代码第一行是最基本的创建一个integer对象的方式。第二行代码就是我们这里要讲的自动装箱。而第三行代码就是第二行代码的本质,也就是说,当你使用自动装箱来得到一个引用数据类型时,jvm实际上调用了valueOf()方法,稍后我们会去研究一下java源码。

自动拆箱:跟自动装箱的方向相反,将Integer及Double这样的包装类的对象重新简化为基本类型的数据。

举个例子:

        1.System.out.println(i1+2);

这句代码就使用了自动拆箱。i1是我们上面通过自动装箱得到的一个integer对象,而这个对象是不能直接进行四则运算的,但是我们却给它+2,这样就必须将integer对象转变为基本数据类型(int),这个过程就是自动拆箱的过程。

p.s.所谓自动,就是说这个过程并不需要程序员去完成,而是jvm自动完成的,jvm会在编译期根据语法决定是否进行装箱和拆箱动作。 
另外,自动拆箱与自动装箱的jdk1.5才引入的新特性,所以如果你的jdk版本低于1.5的话,是不可以这样写的。

2.为什么会有自动拆箱与自动装箱

为什么java要提供这样一个功能呢?我的理解是这样的: 
1.因为懒。假如没有自动拆箱与自动装箱,那么我们的代码是这样的:

    Integer i = new Integer(2);//假如需要一个integer的对象i,值为2
int b=i.intValue();//又需要一个int型的值,大小与i相等
  • 1
  • 2

但是,有了自动拆箱与装箱,我们就可以这么写:

        Integer i = 2;
int b = i;

是不是省了不少事,而且看起来代码更简洁了呢?

2.自动装箱的过程其实可以起到节约内存的作用。我们先看一个例子:

        Integer a = 1;
Integer b = 1;
Integer c = 144;
Integer d = 144;
Integer a1 = new Integer(1);
Integer b1 = new Integer(1);
System.out.println(a == b); //true
System.out.println(a.equals(b)); //true
System.out.println(a1 == b1); //false
System.out.println(a1.equals(b1)); //true
System.out.println(c == d); //false
System.out.println(c.equals(d)); //true

是不是很奇怪,为什么第7行为true而第12行为false呢?这是因为,在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用,始终只存在一个对象 。而如果超过了从–128到127之间的值,被装箱后的Integer对象并不会被重用,即相当于每次装箱时都新建一个 Integer对象。

那么,为什么要这么设计呢?一般来说,小数字的使用频率很高,将小数字保存起来,让其始终仅有一个对象可以节约内存,提高效率。

这其实用到了一种叫做享元模式的设计模式,感兴趣的可以去研究一下这个设计模式。

3.怎么使用自动拆箱与自动装箱

使用方式通过上面的例子大家应该也都清楚了,自动拆箱与装箱实际上就是jvm帮我们去调用一些函数,这样可以使我们省不少事,代码也会看起来更简洁一些,不过在这里还有一点需要强调,先看代码:

Integer a = null;
int b = a;

这么写完全是符合java语法规范的,编译也可以正常通过,但是很明显,运行的时候回抛出空指针异常。所以在这里提醒大家,在使用自动拆箱时,一定要确保包装类的引用不为空。

4.源码剖析

上面提到了几个包装类的方法,我们一Integer类为例,来看一看java源码是什么样子的。首先是valueOf()方法:

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
// 没有设置的话,IngegerCache.high 默认是127
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

上面讲到,在自动装箱时对于值从–128到127之间的值,它们被装箱为Integer对象后,会存在内存中被重用。现在明白是为什么了吧,在调用valueOf()方法的时候,会判断你所给的数是不是在IntegerCache.low 和 i <= IntegerCache.high之间,如果是,那么他就在内存中生成唯一的对象,当你第二次想要生成它的时候,他会把第一次所生成对象的地址给你,不会重新生成。而不在这个范围里的数,你每次所生成的对象都是不同的。

自动装箱池的大小是怎么定义的呢,Integer.java中有这样一个内部类

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.
}
}
high = h; cache = new Integer[(high - low) + 1];
int j = low;
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() {}
}

IntegerCache类(这个是jdk1.8的源码)定义了Integer自动装箱池的大小。从源码中我们可以看到,下界是写死的,就是-128,但是上界却是由参数integerCacheHighPropValue解码得来的,这就表明,其实我们可以通过改变integerCacheHighPropValue值的大小来自定义自动装箱池的大小,当然,一般没人会去改它。

Integer自动装箱池的范围是-128~127 
Byte,Short,Long范围是-128~127 
Character范围是0~127 
Float和Double没有自动装箱池

5.总结

Java通过自动装箱和拆箱的机制,节省了部分内存开销和创建对象的开销,提高了效率同时简化了代码。在使用该机制的时候,需要注意以下几点: 
1.在进行==比较的时候,在自动装箱池范围内的数据的引用是相同的,范围外的是不同的。 
2。在自动拆箱时,要保证包装类的引用不为空。

JavaStudy——Java之自动拆箱与自动装箱的更多相关文章

  1. Java进阶之自动拆箱与自动装箱

    序. java基本类型介绍 java中,基本数据类型一共有8种,详细信息如下表: 类型 大小 范围 默认值 byte 8 -128 - 127 0 short 16 -32768 - 32768 0 ...

  2. 如何理解Java中的自动拆箱和自动装箱?

    小伟刚毕业时面的第一家公司就被面试官给问住了... 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这...这..知识盲区... 回到家后小伟赶紧查资料,我透,这不 ...

  3. 享元模式(FlyWeight Pattern)及其在java自动拆箱、自动装箱中的运用

    本文主要从三个方面着手,第一:简要介绍享元模式.第二:享元模式在基本类型封装类中的运用以Integer为例进行阐述.第三:根据第一.第二的介绍,进而推出java是如何实现自动拆箱与装箱的. 第一:简要 ...

  4. Java语法糖2:自动装箱和自动拆箱

    前言 一开始想学学自动拆箱和自动装箱是被这个名字吸引到,听上去好像很高端的样子,其实自动拆箱.自动装箱是很简单的内容. 自动拆箱和自动装箱 Java为每种基本数据类型都提供了对应的包装器类型.举个例子 ...

  5. java 自动装箱自动拆箱

    1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...

  6. 转!!Java学习之自动装箱和自动拆箱源码分析

    自动装箱(boxing)和自动拆箱(unboxing)   首先了解下Java的四类八种基本数据类型   基本类型 占用空间(Byte) 表示范围 包装器类型 boolean 1/8 true|fal ...

  7. java 自动装箱和自动拆箱

    自动装箱 java执行Integer i = 100:编译器编译成Integer i = Integer.valueOf(100); Integer i = 100; //编译器编译成Integer ...

  8. Java中的自动拆箱装箱(Autoboxing&Unboxing)

    一.基本类型打包器 1.基本类型:long.int.double.float.boolean 2.类类型:Long.Integer.Double.Float.Boolean 区别:基本类型效率更高,类 ...

  9. 别说你不知道java中的包装类,wrapper type,以及容易在自动拆箱中出现的问题

    很多时候,会有人问你,你知道什么是包装类吗? 或者高端一点问你你知道,wrapper type,是什么吗? 然后你就懵逼了,学了java很多时候都不知道这是啥. 其实问你的人,可能只是想问你,java ...

随机推荐

  1. Java 批量导入大量数据

    项目上线测试.产品说导入太慢了,一样的数据量另外一个系统只需要1分钟,我们要5分钟.... 开始以为是因为POI在解析07版本的Excel时候,因为数据量太多所以慢了,后面看下日志,发现是在入库的时候 ...

  2. VR外包团队—国内首家VR虚拟现实主题公园即将在北京推出

    期,美国“The VOID”.澳洲“Zero Latency”两大虚拟现实主题乐园让许多爱好者兴奋至极,门票据说都已经预约到明年2月!在如此巨大的商机面前,谁将抢到国内VR虚拟现实主题公园第一块蛋糕? ...

  3. kafka在windows上的安装、运行

    https://blog.csdn.net/u010283894/article/details/77106159 kafka 创建消费者报错 consumer zookeeper is not a ...

  4. K8S中如何跨namespace 访问服务?为什么ping不通ClusterIP?

    1.K8S中如何跨namespace 访问服务? 2.在Pod中为什么ping不通ClusterIP? 简述: Rancher2.0中的一个用户,在K8S环境中,创建两个namespace,对应用进行 ...

  5. Cordova结合Vue学习Camera

    简单聊两句 学习Vue+Cordova打包编译App,首先你要安装Cordova与vue,在这里本人就不说明了,自行看文档与搜索相关资料. Cordova中文官网地址 Vue中文官网地址 第一步:首先 ...

  6. Java原生API访问MongoDB

    1.pom.xml <dependency> <groupId>org.mongodb</groupId> <artifactId>mongo-java ...

  7. 查看指定库对应GCC版本

    strings /usr/lib/libstdc++.so.6 | grep GLIBCXX

  8. vue的组件之间传值方法

    父组件 <template> <div> 这是父组件 <children v-bind:parentToChild="toChild" v-on:sh ...

  9. vue2.0 实现富文本编辑器功能

    前端富文本编译器使用总结: UEditor:百度前端的开源项目,功能强大,基于 jQuery,但已经没有再维护,而且限定了后端代码,修改起来比较费劲 bootstrap-wysiwyg:微型,易用,小 ...

  10. vue教程自学笔记(二)

    三.模板语法 1.文本 数据绑定最常见的形式就是使用“Mustache”语法 (双大括号) 的文本插值. 通过v-once指令,你也能执行一次性地插值,当数据改变时,插值处的内容不会更新. 2.原始H ...