java有装箱和拆箱吗_Java中装箱和拆箱,你真的都懂么?
在给部门做分享的时候,一位同学提问说一直没搞明白Java的装箱和拆箱,让我给讲解下,所以才有了下面这篇文章:
本次文章根据PPT分享整理而成,会有5点:
1、什么是装箱和拆箱?
2、基本数据类型和包装类型区别
3、示例演示
4、示例代码分析
5、总结
1、什么是装箱和拆箱?
概念:
装箱是将基本类型转换为包装类型
拆箱是想包装类型转换为基本类型
示例:
Integer a = new Integer(1); //装箱
int b = a.intVal(); //拆箱
//JDK1.5开始自动装箱和拆箱
Integer a = 1; //自动装箱
int b = a;//自动拆箱
2、基本数据类型和包装类型区别
概念:
基本数据类型:不需要在堆中分配内存,直接将变量的值存储在堆栈上
包装类型:基本数据类型不具有对象的性质,为了让其具有对象性质,故出现包装类型,将基本类型包装,使其具有对象性质
相互转换:
基本数据类型转换为包装类型
Integer.valueOf(int);
...
包装类型转换为基本数据类型
intValue();
longValue();
...
基本类型和包装类型对应关系
基本数据类型
包装类型
byte
Byte
char
Character
short
Short
int
Integer
long
Long
float
Float
double
Double
boolean
Boolean
3、示例演示
// 如果您能全部回答正确,您可以跳过后面章节:
public static void main(String[] args) {
Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
Integer e = 129;
Integer f = 129;
Long g = 3L;
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(e.equals(f));
System.out.println(g == (a+b));
System.out.println(g.equals(a+b));
}
4、示例代码分析
// 反编译代码,注意:其中中文注释是我加的,便于大家查看
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
4: astore_1
5: iconst_2
6: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
9: astore_2
10: iconst_3
11: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
14: astore_3
15: iconst_3
16: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
19: astore 4
21: sipush 129
24: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
27: astore 5
29: sipush 129
32: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
35: astore 6
37: ldc2_w #3 // long 3l
40: invokestatic #5 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
43: astore 7
45: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
48: aload_3
49: aload 4
51: if_acmpne 58 //c==d,注意这里执行进行了引用比较
54: iconst_1
55: goto 59
58: iconst_0
59: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
62: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
65: aload 5
67: aload 6
69: if_acmpne 76 //e==f,注意这里执行进行了引用比较
72: iconst_1
73: goto 77
76: iconst_0
77: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
80: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
83: aload_3
84: invokevirtual #8 // Method java/lang/Integer.intValue:()I
87: aload_1
88: invokevirtual #8 // Method java/lang/Integer.intValue:()I
91: aload_2
92: invokevirtual #8 // Method java/lang/Integer.intValue:()I
95: iadd // 这里执行了(a+b)
96: if_icmpne 103 // 这里执行c==(a+b),数值比较
99: iconst_1
100: goto 104
103: iconst_0
104: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
107: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
110: aload_3
111: aload_1
112: invokevirtual #8 // Method java/lang/Integer.intValue:()I //拆箱
115: aload_2
116: invokevirtual #8 // Method java/lang/Integer.intValue:()I //拆箱
119: iadd
120: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; //装箱
123: invokevirtual #9 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z //c.equals(a+b)
126: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
129: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
132: aload 5
134: aload 6
136: invokevirtual #9 // Method java/lang/Integer.equals:(Ljava/lang/Object;)Z //e.equals(f)
139: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
142: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
145: aload 7
147: invokevirtual #10 // Method java/lang/Long.longValue:()J //Long 拆箱
150: aload_1
151: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
154: aload_2
155: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
158: iadd // (a+b)
159: i2l // (a+b)结果转换为long类型
160: lcmp // 执行 g == (a+b) 数值比较
161: ifne 168
164: iconst_1
165: goto 169
168: iconst_0
169: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
172: getstatic #6 // Field java/lang/System.out:Ljava/io/PrintStream;
175: aload 7
177: aload_1
178: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
181: aload_2
182: invokevirtual #8 // Method java/lang/Integer.intValue:()I //Integer 拆箱
185: iadd // (a+b)数值相加
186: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer; // Integer装箱
189: invokevirtual #11 // Method java/lang/Long.equals:(Ljava/lang/Object;)Z //执行g.equals(a+b)
192: invokevirtual #7 // Method java/io/PrintStream.println:(Z)V
195: return
}
结合反编译代码,给出的分析:
当我们定义Integer a = 1;时实际执行Integer.valueOf(1),返回Integer对象
// 默认IntegerCache.low = -128, IntegerCache.high = 127
// 但是可以指定"java.lang.Integer.IntegerCache.high"
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
当我们给a、b、c和d赋值时,是在-128-127范围内,直接从缓存中取值,而执行e和f赋值时,会执行new Integer(int),所以他们是不同的Integer对象;
"=="符只有遇到运算符才会执行“自动拆箱”
当执行equals比较,会执行类型判断和数值比较
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
运行结果
c == d:true //没有自动拆箱,直接比较引用
e == f:false //没有自动拆箱,直接比较引用
c == (a+b):true //执行“自动拆箱”,进行数值比较
c.equals(a+b):true //a+b拆箱相加,然后自动装箱,再执行equals
e.equals(f):true //没有执行装箱和拆箱
g == (a+b):true //自动拆箱,执行idd,进行数值比较
g.equals(a+b):false //a+b拆箱相加,然后自动装箱,再执行equals
5、总结
包装类型的数值比较,要注意"=="符号的使用,最好使用equals进行数值比较,因为equals会自动执行拆箱,进行数值比较
java有装箱和拆箱吗_Java中装箱和拆箱,你真的都懂么?相关推荐
- java bufferedwriter会自动创建文件吗_Java中为什么会有包装类?自动拆装箱必要吗?关于Wrapping Class这是重点!...
入题 自动封箱与拆箱人人皆可言之道之,但封箱和拆箱却被多数人略之!如此简单的一个机制,却影射着Java的核心理念,不清楚?继续向下看吧~ Java中的数据类别 目前Java中的数据类别分为两种,一种是 ...
- Java传统的io和nio区别_Java中IO和NIO的本质和区别
简介 终于要写到java中最最让人激动的部分了IO和NIO.IO的全称是input output,是java程序跟外部世界交流的桥梁,IO指的是java.io包中的所有类,他们是从java1.0开始就 ...
- java 抽象类与接口区别是什么_JAVA中抽象类与接口的区别,分别在什么情况下使用它们...
在网上看到很多人问关于"抽象类与接口的区别",因此本人想通过自己多年对JAVA开发的经验来总结一下抽象类与接口的区别以及分别在什么情况下使用它们. 在Java语言中, abstra ...
- java 继承 实现 会重写 方法吗_java 中继承,组合,重载,重写的实现原理 (转)...
我们知道,继承,组合,重载,重写是java语言的面向对象实现的基本特征. 那么在java内部,究竟是如何实现这些面对对象的基本特征的呢? 继承和组合是面向对象中代码复用的主要实现方式,他们可以达到类似 ...
- java类包装器有什么用_Java中的包装器类
java类包装器有什么用 Wrapper class in java are the Object representation of eight primitive types in java. A ...
- Java合并两个int数组合并_Java中如何把两个数组合并为一个
在Java中,如何把两个String[]合并为一个? 看起来是一个很简单的问题.但是如何才能把代码写得高效简洁,却还是值得思考的.这里介绍四种方法,请参考选用. 一.apache-commons 这是 ...
- java.lang类在电脑哪个位置_Java中的java.lang.Class API 详解
且将新火试新茶,诗酒趁年华. 概述 Class是一个位于java.lang包下面的一个类,在Java中每个类实例都有对应的Class对象.类对象是由Java虚拟机(JVM)自动构造的. Class类的 ...
- JAVA偏向锁的什么时候释放_Java中的偏向锁
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 Java偏向锁(Biased Locking)是Java6引入的一项多线程优化. 偏向锁,顾名思义,它会偏向于第一个访问锁的线程,如果在运行过程中,同步锁 ...
- java for(o t :object) 获取顺序号_java中线程的生命周期
线程是java中绕不过去的一个话题, 今天本文将会详细讲解java中线程的生命周期,希望可以给大家一些启发. java中Thread的状态 java中Thread有6种状态,分别是: NEW – 新创 ...
最新文章
- append从一个添加到另一_真特么激动第一个爬虫----爬取豆瓣电影top250
- HTTP 2.0与OkHttp
- 达摩院浙大上海人工智能实验室推出洛犀平台:大小模型端云协同进化
- 计算机桌面窗口移动有虚影,win7系统桌面出现残影影响心情?一招帮你解决问题...
- 机器学习实践:TensorFlow2 多GPU负载不均衡问题
- 语言模型微调领域有哪些最新进展?一文详解最新趋势
- boost::interprocess::windows_shared_memory用法的测试程序
- Android Canvas画图形(更新中)
- shell编程系列26--大型脚本工具开发实战
- Spring.net学习记录
- yii2的Console定时任务创建
- [上海]招募.net网站测试员(实习/见习)
- SPSS学习笔记(一)
- 【Leetcode 刷题题解】python语言+最优美解答+由易到难
- 几个有用的遥感和地理信息网站
- DBCO-PEG4-SUE DBCO-PEG4-蔗糖
- Hinton 深度学习论文总结
- day 86 Vue学习之五DIY脚手架、webpack使用、vue-cli的使用、element-ui
- 【Axure交互教程】图表载入效果(柱状图/折线图/饼图)
- Qt QEvent 介绍
热门文章
- SoJpt Boot 2.2-3.8 发布,Spring Boot 使用 Jfinal 特性极速开发
- Retrofit2源码解析——网络调用流程(下)
- Exchange2013恢复已删除用户邮箱
- 无废话XML--XML约束(DTD)
- 《Linux多线程服务端编程——使用muduo C++网络库》读书笔记
- 【简讯】微软拟发布开源VB6
- 红帽企业linux4参考指南读书笔记-GRUB引导器
- Repeater,DataList,DataGrid 【转】
- ANSYS——后处理中单元表(ELEMENT table)的作用、创建、使用
- python中yield的用法详解——最简单,最清晰的解释(转载)