1、基本概念

字节的单位:byte。位的单位:bit,1byte=8bit

2、8种基本数据类型

4种整型,2种浮点类型,1种用于表示Unicode编码的字符单元的字符类型和1种用于表示真值的boolean类型。

数据类型 浮点型大小(占字节数,2的几次方)  范围  默认值  包装器类型
byte(字节) 8  -128 - 127 0 Byte
shot(短整型) 16 -32768 - 32768 0 Short
int(整型) 32  -2147483648-2147483648 0 Integer
long(长整型) 64 -9233372036854477808-9233372036854477808 0 Long
float(浮点型)  32 -3.40292347E+38-3.40292347E+38 0.0f Float
double(双精度) 64 -1.79769313486231570E+308-1.79769313486231570E+308 0.0d Double
char(字符型) 16 ‘ \u0000 - u\ffff ’  ‘\u0000 ’ Character
boolean(布尔型) 1 true/false false Boolean

3、包装类

  包装类即使把基本类型变成对象类型,包含每种基本数据类型的相关属性如最大值、最小值等,以及相关的操作方法。

4、包装类转换关系
  基本类型  -->  包装器类
    Integer obj=new Integer(10);
  包装器类 -->  基本类型
    int num=obj.intValue();
  字符串 --> 包装器类
    Integer obj=new Integer("100");
  字符串   -->   基本类型
    int num=Integer.parseInt("-45.36");

5、自动装包/拆包(Autoboxing/unboxing)

基本类与包装类的转换,则是装包与拆包
  自动装包/拆包大大方便了基本类型数据和它们包装类地使用。
  自动装包:基本类型自动转为包装类.(int >> Integer)
  自动拆包:包装类自动转为基本类型.(Integer >> int)

int 是基本类型,直接存储数值 
  Integer是对象类,new一个对象时用一个引用指向这个对象
    Java把内存划分成两种:一种是栈内存,另一种是堆内存 
    在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配,而实际的对象是在存储堆内存中 
    比如
    int i = 10;       ----直接在栈中分配空间 
    Integer j = new Integr(5);     ----对象是在堆内存中,而j(引用变量)是在栈内存中 
 在堆中分配的内存,由java虚拟机的自动垃圾回收器来管理。 因为在堆中分配空间所需的时间远大于从栈中分配存储空间

一.什么是装箱?什么是拆箱?

二.装箱和拆箱是如何实现的

三.面试中相关的问题

一.什么是装箱?什么是拆箱?

  在前面的文章中提到,Java为每种基本数据类型都提供了对应的包装器类型,至于为什么会为每种基本数据类型提供包装器类型在此不进行阐述,有兴趣的朋友可以查阅相关资料。在Java SE5之前,如果要生成一个数值为10的Integer对象,必须这样进行:

Integer i = new Integer(10);

而在从Java SE5开始就提供了自动装箱的特性,如果要生成一个数值为10的Integer对象,只需要这样就可以了:

Integer i = 10;

这个过程中会自动根据数值创建对应的 Integer对象,这就是装箱。

  那什么是拆箱呢?顾名思义,跟装箱对应,就是自动将包装器类型转换为基本数据类型:

Integer i = 10;  //装箱

int n = i;   //拆箱
简单一点说,装箱就是  自动将基本数据类型转换为包装器类型;拆箱就是  自动将包装器类型转换为基本数据类型。
 
int(4字节) Integer
byte(1字节) Byte
short(2字节) Short
long(8字节) Long
float(4字节) Float
double(8字节)

Double

char(2字节) Character
boolean(未定) Boolean
接下来了解一下装箱和拆箱是如何实现的。
public class Main {

    public static void main(String[] args) {
         
        Integer i = 10;
        int n = i;
    }
}
 
反编译class文件之后得到如下内容:
 

从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是Integer的valueOf(int)方法。而在拆箱的时候自动调用的是Integer的intValue方法。

  其他的也类似,比如Double、Character,不相信的朋友可以自己手动尝试一下。

  因此可以用一句话总结装箱和拆箱的实现过程:

  装箱过程是通过调用包装器的valueOf方法实现的,而拆箱过程是通过调用包装器的 xxxValue方法实现的。(xxx代表对应的基本数据类型)。

三.面试中相关的问题

  虽然大多数人对装箱和拆箱的概念都清楚,但是在面试和笔试中遇到了与装箱和拆箱的问题却不一定会答得上来。下面列举一些常见的与装箱/拆箱有关的面试题。

1.下面这段代码的输出结果是什么?

答案是i1=i2  true;

i3=i4 false;

为什么会出现这样的结果?输出结果表明i1和i2指向的是同一个对象,而i3和i4指向的是不同的对象.

只需一看源码便知究竟,下面这段代码是Integer的valueOf方法的具体实现.

在通过valueOf方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用;否则创建一个新的Integer对象。

上面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

2.下面这段代码的输出结果是什么?

false
false

至于具体为什么,读者可以去查看Double类的valueOf的实现。

  在这里只解释一下为什么Double类的valueOf方法会采用与Integer类的valueOf方法不同的实现。很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

  注意,Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。

     Double、Float的valueOf方法的实现是类似的。

Boolean i11 = false;
Boolean i21 = false;
Boolean i31 = true;
Boolean i41 = true;

System.out.println(i11==i21);
System.out.println(i31==i41);

true
true

4.谈谈Integer i = new Integer(xxx)和Integer i =xxx;这两种方式的区别。

  当然,这个题目属于比较宽泛类型的。但是要点一定要答上,我总结一下主要有以下这两点区别:

  1)第一种方式不会触发自动装箱的过程;而第二种方式会触发;

  2)在执行效率和资源占用上的区别。第二种方式的执行效率和资源占用在一般性情况下要优于第一种情况(注意这并不是绝对的)。

 
 
   Integer a = 1;
        Integer b = 2;
        Integer c = 3;
        Integer d = 3;
        Integer e = 321;
        Integer f = 321;
        Long g = 3L;
        Long h = 2L;
         
        System.out.println(c==d);
        System.out.println(e==f);
        System.out.println(c==(a+b));
        System.out.println(c.equals(a+b));
        System.out.println(g==(a+b));
        System.out.println(g.equals(a+b));
        System.out.println(g.equals(a+h));
 

true
false
true
true
true
false
true

这里面需要注意的是:当 "=="运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。另外,对于包装器类型,equals方法并不会进行类型转换。明白了这2点之后,上面的输出结果便一目了然。

第一个和第二个输出结果没有什么疑问。第三句由于  a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),因此它们比较的是数值是否相等。而对于c.equals(a+b)会先触发自动拆箱过程,再触发自动装箱过程,也就是说a+b,会先各自调用intValue方法,得到了加法运算后的数值之后,便调用Integer.valueOf方法,再进行equals比较。同理对于后面的也是这样,不过要注意倒数第二个和最后一个输出的结果(如果数值是int类型的,装箱过程调用的是Integer.valueOf;如果是long类型的,装箱调用的Long.valueOf方法)。

 
 
 
 
 
 
 
 
 
 

java的封箱和拆箱的更多相关文章

  1. java 自动装箱自动拆箱

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

  2. Java 自动装箱与拆箱

    Java 自动装箱与拆箱(Autoboxing and unboxing)   什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供 ...

  3. 【转】java 自动装箱与拆箱

    java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...

  4. [转]JAVA自动装箱和拆箱

    http://www.cnblogs.com/dolphin0520/p/3780005.html 1.Java数据类型 装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类 ...

  5. Java进阶(三十七)java 自动装箱与拆箱

    Java进阶(三十七)java 自动装箱与拆箱 前言 这个是jdk1.5以后才引入的新的内容.java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装称为装箱,解包装称为 ...

  6. JAVA基础之——三大特征、接口和抽象类区别、重载和重写区别、==和equals区别、JAVA自动装箱和拆箱

    1 java三大特征 1)封装:即class,把一类实体定义成类,该类有变量和方法. 2)继承:从已有的父类中派生出子类,子类实现父类的抽象方法. 3)多态:通过父类对象可以引用不同的子类,从而实现不 ...

  7. Java的自动装箱/拆箱

    概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...

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

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

  9. 深入理解Java之装箱与拆箱

    一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...

随机推荐

  1. 类 Fabric 主机管理程序开发

    类 Fabric 主机管理程序开发:1. 运行程序列出主机组或者主机列表2. 选择指定主机或主机组3. 选择让主机或者主机组执行命令或者向其传输文件(上传/下载4. 充分使用多线程或多进程5. 不同主 ...

  2. swift--如何设置子视图alpha不同于父视图

    //1.2加入商家标题评分容器 let titleWarp=UIView(frame: CGRectMake(, , screenObject.width, )); titleWarp.backgro ...

  3. JavaSE 学习笔记之Import 导入(十二)

    Import - 导入:类名称变长,写起来很麻烦.为了简化,使用了一个关键字:import,可以使用这个关键字导入指定包中的类.记住:实际开发时,到的哪个类就导入哪个类,不建议使用*. import ...

  4. springCloud学习-服务消费者(Feign)

    1.简介 Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单.使用Feign,只需要创建一个接口并注解.它具有可插拔的注解特性,可使用Feign 注解和JAX-RS注解.Fei ...

  5. RDS For MySQL 字符集相关说明

    https://help.aliyun.com/knowledge_detail/41706.html?spm=5176.7841698.2.9.F5YjI5 字符序命名规则 字符集相关 MySQL  ...

  6. [Mini Program] 尺寸单位 rpx

    So each phone's width is 750rpx. And according to the device ratio (width:height), we can calucalate ...

  7. STM32F407VG (五)定时器

    一.定时器节本分类和主要特点 1.STM32定时器分类: 1)看门狗定时器 2)SysTick定时器 3)RTC定时器 4)通用定时器 a)通用定时器TIM2~TIM5, 当中TIM2和TIM5是32 ...

  8. C++对象模型——关键词所带来的差异(第一章)

    1.2    关键词所带来的差异 (A Keyword Distinction) 假设不是为了努力维护与C之间的兼容性.C++能够比方今更简单.举个样例,假设没有八种整数须要支持的话,overload ...

  9. 反射调用android系统级API函数

    try { Class<?> mClass = Class.forName("com.android.server.wifi.WifiSettingsStore"); ...

  10. php file_get_contents遇到https的处理办法

    最近调整了文件上传后的资源路径,导致pageOffice在线编辑功能无法正常使用,每一次打开文件都报错:该文件为0字节.仔细看了一下程序,整理逻辑流程如下图: 增加日志后发现,保存在服务器路径下的该条 ...