java自动包装与解包
关于java的自动包装机制想必大家都用过吧,一般这些机制都用于在往容器中存储基本类型数据的时候,因为容器中不允许存在基本数据类型,所以就会调用自动包装机制,将基本数据类型转换为对象,将基本数据保存在对象中,并且提供一些基本方法,但是自动包装机制存在一些陷阱,使用不当就会出错
先看看下面一个例子吧
package test;
public class AutoPack {
public static void main(String[] args) {
Integer a=1;
Integer b=2;
Integer c=3;
Integer d = 3;
Integer e=321;
Integer f=321;
Long g=3L;
System.out.println(c==d);//true
System.out.println(e==f);//false
System.out.println(c==(a+b));//true
System.out.println(c.equals(a+b));//true
System.out.println(g==(a+b));//true
System.out.println(g.equals(a+b));//false //不是同一类型
System.out.println(g.equals((long)(a+b)));//true 首先比较是不是同一类型,再比较值
}
}
上面例子中的输出你都做对了吗?如果有疑惑,请看我下面的解答
首先我们得请出一个前提:对于对象类型,==符号表示比较对象的所在的物理地址,equals方法比较的是对象的值(前提是两者属于同一个对象类型),而对于基本数据类型,==符号比较的是值
然后我们再来看一看Integer的内部实现,Integer有三种创建方法,分别是
Integer a = new Integer(1); //创建新的类 Integer b = Integer.valueOf(2); Integer c = 3; //自动包装,会调用valueOf方法
上面的三种方法中,第一种方法所创建的是一个全新的Integer对象,这样的对象在用 == 比较时是肯定不相同的,只能通过 equals 方法进行比较
,第二种方法和第三种方法都显式或者隐式的调用了ValueOf方法,所以下面我们来看一下ValueOf方法
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
valueOf方法首先判断数字是否大于low(-128)并且小于数字(127),如果满足条件,则直接从IntegerCache中返回这个数(IntegerCache用于存储一些常用的数,防止重复创建),
所以只要是用 valueOf 或者Integer = num 这两种方法创建的对象,其值小于127且大于-128的,无论对其进行 == 比较还是equals 比较,都是true
对于不满足这个范围的数,无论怎么创建,都是一个新的对象,是只能通过equals比较的,接下来我们再看看equals方法
public boolean equals(Object obj) {
if (obj instanceof Integer) {
return value == ((Integer)obj).intValue();
}
return false;
}
equals很简单,首先比较两者的类型是否一致,如果类型不一致,直接返回false,否则,再比较两者的值,相同则返回true
那么现在你再回过头去看上面的输出,是不是清晰明了呢
还有一点就是上面的第三个和第五个输出了,因为等式两边都运用了算术运算符,所以会自动拆包,拆包后比较的就是两者的value了
那么下面来总结一下:
1.在==运算的时候,如果两端中任何一端含有算术表达式,就会发生自动解包,这时比较的是值
2.在==运算时,两端都没有算术表达式,就不会解包,这时比较的是对象的地址(这样使用很危险)
3.equals可以比较对象的值,比较推荐使用,但前提是要相同对象类型,比如在上面倒数第二个输出中,虽然值相等,但是一个是Integer,一个是Long,就会返回false,但是如果是基本数据类型int 和 long ,他们其实是可以相等的
4.Integer中有IntegerCache,会对-128到127的值进行缓存,所以在这个范围内只要不用new 关键字创建Integer对象,那么这些对象都是同一个对象
java自动包装与解包的更多相关文章
- Java的原始类型自动包装与解包机制
java5之后对原始数据类型如int.char.long等基本数据类型有自动打包成相应的复合类型Integer.Character.Long等的机制:也可以将复合类型自动转换为原始类型. 这取决于程序 ...
- Java之集合初探(二)Iterator(迭代器),collections,打包/解包(装箱拆箱),泛型(Generic),comparable接口
Iterator(迭代器) 所有实现了Collection接口的容器都有一个iterator方法, 用来返回一个实现了Iterator接口的对象 Iterator对象称作迭代器, 用来方便的实现对容器 ...
- Java、javax、org、sun、Java.util等常用包的区别、详解、实例
Java.javax.org.sun包都是jdk提供的类包,且都是在rt.jar中.rt.jar是JAVA基础类库(java核心框架中很重要的包),包含lang在内的大部分功能,而且rt.jar默认就 ...
- Java内部类详解
Java内部类详解 说起内部类这个词,想必很多人都不陌生,但是又会觉得不熟悉.原因是平时编写代码时可能用到的场景不多,用得最多的是在有事件监听的情况下,并且即使用到也很少去总结内部类的用法.今天我们就 ...
- C++调用JAVA方法详解
C++调用JAVA方法详解 博客分类: 本文主要参考http://tech.ccidnet.com/art/1081/20050413/237901_1.html 上的文章. C++ ...
- C#调用java类、jar包方法(转)
一.将已经编译后的java中Class文件进行打包:打包命令JAR 如:将某目录下的所有class文件夹全部进行打包处理: 使用的命令:jar cvf test.jar -C com/ . 其中tes ...
- Java虚拟机详解----JVM常见问题总结
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- C#调用java类、jar包方法
一.将已经编译后的java中Class文件进行打包:打包命令JAR 如:将某目录下的所有class文件夹全部进行打包处理: 使用的命令:jar cvf test.jar -C com/ . 其中tes ...
- java基础十[包、Jar存档文件和部署](阅读Head First Java记录)
将Java的class文件生成为可执行的Java应用程序.Java应用程序有三种:完全在本机执行的Jar(例如本机的GUI可执行程序):完全在服务器端远程执行的(例如浏览器来进行存取):介于两者之间的 ...
随机推荐
- OFbiz实体引擎
安全可靠的数据存储是数据管理战略的关键业务,OFbiz认真对待数据管理.不把全部繁琐和easy出错的数据管理任务留给应用开发人员.OFbiz在设计和实现阶段非常好的贯彻了这个理念. 实体引擎是数据库无 ...
- Linux学习笔记:系统启动引导过程
Linux系统启动引导过程 近期发现自己在仅仅是掌握上有几个比較硬的伤: 一.知识体系碎片,比方Linux,这学点那学点,结果没有成体系,串不起来: 二.记忆时间短暂,非常多的内容学了就忘,最后的结果 ...
- 大话设计模式C++实现-第14章-观察者模式
一.UML图 关键词:Subject维护一个Observer列表.Subject运行Notify()时就运行列表中的每一个Observer的Update(). 二.概念 观察者模式:定义了一种一对多的 ...
- Bean Query 第一个版本号(1.0.0)已公布
BeanQuery 是一个把对象转换为Map的Java工具库. 支持选择Bean中的一些属性.对结果进行排序和依照条件查询. 不只能够作用于顶层对象,也能够作用于子对象.很多其它具体的介绍能够看我的博 ...
- SpringMVC_架构 --跟海涛学SpringMVC(学习笔记)
重点: 1.工作流程及实现原理 2.配置及使用方法 3.共同函数 前言 1.2.模型: 1.2.1.此处模型使用JavaBean,可能造成JavaBean组件类很庞大,一般现在项目都是采用三层架构,而 ...
- mysql数据库存放路径
在你的my.ini 文件中定义的参数 datadir 指定的目录中. SQL code ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 mysql> select @@da ...
- Delphi的函数指针
不求全面,先留个爪: TNotifyEvent = procedure(Sender: TObject) of object; TMethod = record Code, Data: Pointer ...
- Windows 异步IO操作
Windows提供了4种不同的方法来接收I/O请求已经完成的通知:触发设备内核对象.触发事件内核对象.可提醒I/O和I/O完成端口. Windows的异步I/O 当线程向设备发起一个I/O异步 ...
- lambda和抽象类
lambda的使用条件是‘一个接口仅有一个待实现的方法’: so,lambda不能使用在抽象类上,使用后或提示‘Target type of a lambda conversion must be a ...
- YTU 1075: Time
1075: Time 时间限制: 1 Sec 内存限制: 128 MB 提交: 7 解决: 7 [提交][状态][讨论版] 题目描述 Digital clock use 4 digits to e ...