Java数据类型(2)------自动封装拆箱
目的:
自动装箱和拆箱从Java 1.5开始引入,目的是将原始类型值转自动地转换成对应的对象,以使用对象的API和引用类型操作。自动装箱与拆箱的机制可以让我们在Java的变量赋值或者是方法调用等情况下使用原始类型或者对象类型更加简单直接。
定义:
自动装箱就是Java自动将原始类型值转换成对应的对象,比如将int的变量转换成Integer对象,这个过程叫做装箱,反之将Integer对象转换成int类型值,这个过程叫做拆箱。因为这里的装箱和拆箱是自动进行的非人为转换,所以就称作为自动装箱和拆箱。原始类型byte,short,char,int,long,float,double和boolean对应的封装类为Byte,Short,Character,Integer,Long,Float,Double,Boolean。
实现:
自动装箱时编译器调用valueOf将原始类型值转换成对象,同时自动拆箱时,编译器通过调用类似intValue(),doubleValue()这类的方法将对象转换成原始类型值。
发生时间:
有一个方法,接受一个对象类型的参数,如果我们传递一个原始类型值,那么Java会自动讲这个原始类型值转换成与之对应的对象。
List<Integer> list = new ArrayList<Integer>();
// 自动装箱
list.add(1);
list.add(2);
// 拆箱
int i = list.get(0);
int ii = list.get(1);
自动装箱的弊端:
自动装箱有一个问题,那就是在一个循环中进行自动装箱操作的情况,如下面的例子就会创建多余的对象,影响程序的性能。
Integer sum = 0;
for(int i=1000; i<5000; i++){
sum+=i;
}
上面的代码sum+=i可以看成sum = sum + i,但是==、+、-、*、/这个操作符不适用于Integer对象,首先sum进行自动拆箱操作,进行数值相加操作,最后发生自动装箱操作转换成Integer对象。其过程如下
int temp = sum.intValue() + i;
Integer sum = new Integer(temp);
由于我们这里声明的sum为Integer类型,在上面的循环中会创建将近5000个无用的Integer对象,在这样庞大的循环中,会降低程序的性能并且加重了垃圾回收的工作量。因此,需要注意到这一点,正确地声明变量类型,避免因为自动装箱引起的性能问题.
注意事项:
自动装箱和拆箱可以让代码简洁,但是,我们在使用的时候应该注意下,否则会发生一些问题。
1.比较
”==“可以用于原始值进行比较,也可以用于对象进行比较,当用于对象与对象之间比较时,比较的不是对象代表的值,而是检查两个对象是否是同一对象,即检查引用地址是否相同。这个比较过程中没有自动装箱发生。进行对象值比较不应该使用”==“,而应该使用对象对应的equals方法。
// 1
int i1=1;
int i2=1;
System.out.println(i2==i1);// true
// 2
Integer I1=1;
System.out.println(I1==i1);// true
Integer I2=1;
System.out.println(I1==I2);// true
// 3
Integer I3 = 128;// 触发自动封装
Integer I4 = 128;
System.out.println(I3==I4);// false
// 4
Integer I5= new Integer(1);// 不触发自动封装
Integer I6= new Integer(1);
System.out.println(I5==I6); // false
值得注意的是第2个小例子的第二个比较,这是一种极端情况。I1和I2的初始化都发生了自动装箱操作。但是处于节省内存的考虑,JVM会缓存-128到127的Integer对象。因为I1和I2实际上是同一个对象。所以使用”==“比较返回true,而第三个小例子使用‘==’返回false。
注:自动封装的函数
public static Integer valueOf(int i) {
return i >= 128 || i < -128 ? new Integer(i) : SMALL_VALUES[i + 128];
}
private static final Integer[] SMALL_VALUES = new Integer[256];
2.容易混乱的对象和原始数据值
另一个需要避免的问题就是混乱使用对象和原始数据值,一个具体的例子就是当我们在一个原始数据值与一个对象进行比较或赋值时,如果这个对象没有进行初始化或者为Null,在自动拆箱过程中obj.xxxValue,会抛出NullPointerException,如下面的代码
private static Integer count;
if(count>=0){
System.out.println(11111111111L);
}
3.缓存的对象
在Java中,会对-128到127的Integer对象进行缓存,当创建新的Integer对象时,如果符合这个这个范围,并且已有存在的相同值的对象,则返回这个对象,否则创建新的Integer对象。
4.生成无用对象
因为自动装箱会隐式地创建对象,像前面提到的那样,如果在一个循环体中,会创建无用的中间对象,这样会增加GC压力,拉低程序的性能。所以在写循环时一定要注意代码,避免引入不必要的自动装箱操作。
Java数据类型(2)------自动封装拆箱的更多相关文章
- Java中的自动装箱拆箱
Java中的自动装箱拆箱 一.自动装箱与自动拆箱 自动装箱就是将基本数据类型转换为包装类类型,自动拆箱就是将包装类类型转换为基本数据类型. 1 // 自动装箱 2 Integer total = 90 ...
- Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法?
参考:http://blog.csdn.net/mazhimazh/article/details/16799925 1. Java八种基本数据类型的大小,以及封装类,自动装箱/拆箱的用法? 原始类型 ...
- JAVA自动装箱拆箱与常量池
java 自动装箱与拆箱 这个是jdk1.5以后才引入的新的内容,作为秉承发表是最好的记忆,毅然决定还是用一篇博客来代替我的记忆: java语言规范中说道:在许多情况下包装与解包装是由编译器自行完成的 ...
- Java 的自动装箱拆箱
Java 是面向对象的语言,其基本数据类型也就有了相对应的类,称为包装类.以下是基本数据类型对应的包装类: 基本数据类型 包装类 byte(1字节) Byte short(2字节) Short int ...
- Java SE之装箱与拆箱【基本数据类型的包装类/==与equals方法】
对象包装器.自动装箱与拆箱 2016/11/30 晚 特点 1.所有的基本类型都有一个包装器类与之对应.[Integer,Boolean,Long,Character,Shor ...
- java基础1.5版后新特性 自动装箱拆箱 Date SimpleDateFormat Calendar.getInstance()获得一个日历对象 抽象不要生成对象 get set add System.arrayCopy()用于集合等的扩容
8种基本数据类型的8种包装类 byte Byte short Short int Integer long Long float Float double Double char Character ...
- Java的自动装箱/拆箱
概述 自JDK1.5开始, 引入了自动装箱/拆箱这一语法糖, 它使程序员的代码变得更加简洁, 不再需要进行显式转换.基本类型与包装类型在某些操作符的作用下, 包装类型调用valueOf()方法将原始类 ...
- JAVA的自动装箱拆箱
转自:http://www.cnblogs.com/danne823/archive/2011/04/22/2025332.html 蛋呢 的空间 ??什么是自动装箱拆箱 基本数据类型的自动装箱(a ...
- java自动装箱拆箱总结
对于java1.5引入的自动装箱拆箱,之前只是知道一点点,最近在看一篇博客时发现自己对自动装箱拆箱这个特性了解的太少了,所以今天研究了下这个特性.以下是结合测试代码进行的总结. 测试代码: int a ...
随机推荐
- requests--重定向,序列化
重定向 默认情况下,除了 HEAD, Requests 会自动处理所有重定向.可以使用响应对象的 history 方法来追踪重定向. Response.history 是一个 Response 对象的 ...
- [LeetCode] 896. Monotonic Array 单调数组
An array is monotonic if it is either monotone increasing or monotone decreasing. An array A is mono ...
- [LeetCode] 179. Largest Number 最大组合数
Given a list of non negative integers, arrange them such that they form the largest number. Example ...
- XC7K325TFFG900 Device 内部结构图
- js 宏任务和微任务
.宏任务(macrotask )和微任务(microtask ) macrotask 和 microtask 表示异步任务的两种分类. 在挂起任务时,JS 引擎会将所有任务按照类别分到这两个队列中,首 ...
- 移动端布局方案—vw+rem
前言 首先你要知道 vw 和 rem 是什么?怎么使用? ①:简单来说 vw 是视口单位,相当于把视口等分成了100,1vw = 1; ②:rem是相对单位,设置根元素 html 的 font-siz ...
- VisualHull && association4D 观摩记录
简单记录一下自己对VisualHull 和 association4D 两个程序的理解,没有别的意思(当然是真的 由于进度还很慢,暂时只是简单记录一下发现的点和踩过的坑,做完再把资料汇总. Visua ...
- 用cp命令拷贝文件,源目录后带不带斜杠的区别
当我还是Linux超级傻白的时候,需要拷贝一个很大的数据集,然后再拷贝源文件夹的后面跟了一个前倾斜杠,然后就发现居然拷贝的是整个文件夹里的东西,而不是文件夹本身.事儿倒是不大,我重新建一个文件夹,把这 ...
- Java内部类是如何实现的
内部类(inner class)是定义在另一个类中的类. 内部类方法可以访问该类定义所在的作用域中的数据,包括私有的数据. 内部类可以对同一个包中的其他类隐藏起来 当想定义一个回调函数且不想编写大量代 ...
- nohup 启动后台应用
nohup java -Xmx1024M -Xms1024M -jar app.jar --logging.level=warn --logging.path=/var/log/app--server ...