java的封箱和拆箱
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;
}
}
从反编译得到的字节码内容可以看出,在装箱的时候自动调用的是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的封箱和拆箱的更多相关文章
- java 自动装箱自动拆箱
1.Java数据类型 在介绍Java的自动装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference ...
- Java 自动装箱与拆箱
Java 自动装箱与拆箱(Autoboxing and unboxing) 什么是自动装箱拆箱 基本数据类型的自动装箱(autoboxing).拆箱(unboxing)是自J2SE 5.0开始提供 ...
- 【转】java 自动装箱与拆箱
java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...
- [转]JAVA自动装箱和拆箱
http://www.cnblogs.com/dolphin0520/p/3780005.html 1.Java数据类型 装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类 ...
- Java进阶(三十七)java 自动装箱与拆箱
Java进阶(三十七)java 自动装箱与拆箱 前言 这个是jdk1.5以后才引入的新的内容.java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的(在这种情况下包装称为装箱,解包装称为 ...
- JAVA基础之——三大特征、接口和抽象类区别、重载和重写区别、==和equals区别、JAVA自动装箱和拆箱
1 java三大特征 1)封装:即class,把一类实体定义成类,该类有变量和方法. 2)继承:从已有的父类中派生出子类,子类实现父类的抽象方法. 3)多态:通过父类对象可以引用不同的子类,从而实现不 ...
- Java的自动装箱/拆箱
概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...
- 如何理解Java中的自动拆箱和自动装箱?
小伟刚毕业时面的第一家公司就被面试官给问住了... 如何理解Java中的自动拆箱和自动装箱? 自动拆箱?自动装箱?什么鬼,听都没听过啊,这...这..知识盲区... 回到家后小伟赶紧查资料,我透,这不 ...
- 深入理解Java之装箱与拆箱
一.Java数据类型 1.在说装箱与拆箱之前,先说一下Java的基本数据类型,Java从数据类型上可以划分为值类型与引用类型,值类型是四类八种,分别是: 整数型:byte̵,short̵,int̵,l ...
随机推荐
- HDU - 2159 FATE(二维dp之01背包问题)
题目: 思路: 二维dp,完全背包,状态转移方程dp[i][z] = max(dp[i][z], dp[i-1][z-a[j]]+b[j]),dp[i][z]表示在杀i个怪,消耗z个容忍度的情况下 ...
- Git 基础教程 之 标签
所谓标签:就是一个让人容易记住的有意义的名字,与某个commit绑在一起. 创建标签:①切回需要打标签的分支上 ② git tag <name> 默认标 ...
- JSTL 实现 为Select赋多个值
需要注意需要在.jsp文件中引入相应的类库 <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core ...
- 【codeforces 514C】Watto and Mechanism(字典树做法)
[题目链接]:http://codeforces.com/contest/514/problem/C [题意] 给你n个字符串; 然后给你m个询问;->m个字符串 对于每一个询问字符串 你需要在 ...
- noip模拟赛 PA
分析:很显然这是一道搜索题,可能是由于我的搜索打的太不美观了,这道题又WA又T......如果对每一个询问都做一次bfs是肯定会T的,注意到前70%的数据范围,N的值都相等,我们可以把给定N的所有情况 ...
- poj 2553强连通+缩点
/*先吐槽下,刚开始没看懂题,以为只能是一个连通图0T0 题意:给你一个有向图,求G图中从v可达的所有点w,也都可以达到v,这样的v称为sink.求这样的v. 解;求强连通+缩点.求所有出度为0的点即 ...
- 数字统计(2010年NOIP全国联赛普及组)
题目描述 请统计某个给定范围[L, R]的所有整数中,数字 2 出现的次数. 比如给定范围[2, 22],数字 2 在数 2 中出现了 1 次,在数 12 中出现 1 次,在数 20 中出 现 1 次 ...
- Pie POJ 3122 二分搜索
Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 17324 Accepted: 5835 Special Judge ...
- ELECTRON开发环境配置方法
1.下载并安装Node.js 下载地址:https://nodejs.org/en/download/current/ 安装之后进行验证 2.下载并这装electron 安装命令:npm instal ...
- 民意调查Django实现(三)
我们接着第二小节的開始继续我们的旅程. 我们会继续Web-poll应用.而且将会专注于创建公共接口 - "Views". 哲学思想 一个视图是你的Django应用中的一个Web页面 ...