手动拆装箱java代码 java拆箱装箱原理

关于java封装与拆装1.如果你是用Integer i=0;和Integer j=0;这个时候就是自动拆箱,把对象i和j自动拆成对应的基础类型即int型 。int是原生类型,while(i=ji=ji!=j)语句中i=j和i=j满足 , 但是i!=j不满足,因为原生类型中i==j 。所以整个while语句不成立,当然也就不输出"0000"了
2.但是用Integer i=new Integer(0);Integer j=new Integer(0);的话,i和j是定义的对象 , 虽然对象的值都是0,但是这两个对象对应内存中不同的引用地方,因此 i!=j成立,整个while语句也就成立,也就会不断的输出"0000"了 。
java double拆装箱会不会影响计算装箱 相当于将double包装成Double手动拆装箱java代码;
拆箱手动拆装箱java代码,就是跟装箱的方向相反手动拆装箱java代码,将Double这样的引用类型的对象重新简化为double;
jdk1.5以后 , 可自动进行的装箱和拆箱的操作,比较方便;
---------------
摘自effective java (第五条,避免创建不必要的对象)
考虑下面的程序,它计算所有int正值的和,为此,程序必须使用long算法,代码如下:
[java] view plaincopy
public static void main(String[] args) {
Long sum =0L;
for(long i =0;iInteger.MAX_VALUE;i){
sum =i;
}
System.out.println(sum);
}
这段代码算出的答案是正确的 , 但是比实际情况要更慢一些,只因为打错手动拆装箱java代码了一个字符 。变量sum被声明为Long而不是long,意味着程序构造了大约2的31次方个多余的Long实例(大约每次往sum中增加long时候构造一个实例) 。将sum从Long改为long后,代码的运行时间在手动拆装箱java代码我的电脑上从43秒减少到6.8秒 。结论很明显:要优先使用基本类型而不是装箱基本类型 , 要当心无意识的自动装箱 。
-----------------
java 什么是拆箱和装箱,拆箱和装箱 嘛用?。浚浚?/h2>详解Java的自动装箱与拆箱(Autoboxing and unboxing)
一、什么是自动装箱拆箱
很简单手动拆装箱java代码,下面两句代码就可以看到装箱和拆箱过程
//自动装箱
Integer total = 99;
//自定拆箱
int totalprim = total;
简单一点说 , 装箱就是自动将基本数据类型转换为包装器类型手动拆装箱java代码;拆箱就是自动将包装器类型转换为基本数据类型 。
下面我们来看看需要装箱拆箱的类型有哪些手动拆装箱java代码:
这个过程是自动执行的,那么我们需要看看它的执行过程:
public class Main {
public static void main(String[] args) {
//自动装箱
Integer total = 99;
//自定拆箱
int totalprim = total;
}
}
反编译class文件之后得到如下内容:
javap -c StringTest
Integer total = 99;
执行上面那句代码的时候,系统为我们执行了:
Integer total = Integer.valueOf(99);
int totalprim = total;
执行上面那句代码的时候,系统为我们执行了:
int totalprim = total.intValue();
我们现在就以Integer为例,来分析一下它的源码:
1、首先来看看Integer.valueOf函数
public static Integer valueOf(int i) {
returni = 128 || i-128 ? new Integer(i) : SMALL_VALUES[i128];
}
它会首先判断i的大?。喝绻鹖小于-128或者大于等于128,就创建一个Integer对象,否则执行SMALL_VALUES[i128] 。
首先我们来看看Integer的构造函数:
private final int value;
public Integer(int value) {
this.value = https://www.04ip.com/post/value;
}
public Integer(String string) throws NumberFormatException {
this(parseInt(string));
}
它里面定义了一个value变量 , 创建一个Integer对象,就会给这个变量初始化 。第二个传入的是一个String变量,它会先把它转换成一个int值,然后进行初始化 。
下面看看SMALL_VALUES[i128]是什么东西:
private static final Integer[] SMALL_VALUES = new Integer[256];
它是一个静态的Integer数组对象,也就是说最终valueOf返回的都是一个Integer对象 。
所以我们这里可以总结一点:装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能 。
2、接着看看intValue函数
@Override
public int intValue() {
return value;
}
这个很简单 , 直接返回value值即可 。
二、相关问题
上面我们看到在Integer的构造函数中,它分两种情况:
1、i = 128 || i-128 ===== new Integer(i)
2、i128i = -128 ===== SMALL_VALUES[i128]
private static final Integer[] SMALL_VALUES = new Integer[256];
SMALL_VALUES本来已经被创建好,也就是说在i = 128 || i-128是会创建不同的对象,在i128i = -128会根据i的值返回已经创建好的指定的对象 。
说这些可能还不是很明白,下面我们来举个例子吧:
public class Main {public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//false
}
}
代码的后面,我们可以看到它们的执行结果是不一样的 , 为什么,在看看我们上面的说明 。
1、i1和i2会进行自动装箱,执行了valueOf函数,它们的值在(-128,128]这个范围内,它们会拿到SMALL_VALUES数组里面的同一个对象SMALL_VALUES[228],它们引用到了同一个Integer对象,所以它们肯定是相等的 。
2、i3和i4也会进行自动装箱 , 执行了valueOf函数 , 它们的值大于128,所以会执行new Integer(200),也就是说它们会分别创建两个不同的对象,所以它们肯定不等 。
下面我们来看看另外一个例子:
public class Main {public static void main(String[] args) {
Double i1 = 100.0;
Double i2 = 100.0;
Double i3 = 200.0;
Double i4 = 200.0;
System.out.println(i1==i2); //false
System.out.println(i3==i4); //false
}
}
看看上面的执行结果,跟Integer不一样,这样也不必奇怪 , 因为它们的valueOf实现不一样 , 结果肯定不一样,那为什么它们不统一一下呢?
这个很好理解 , 因为对于Integer,在(-128,128]之间只有固定的256个值,所以为了避免多次创建对象,我们事先就创建好一个大小为256的Integer数组SMALL_VALUES , 所以如果值在这个范围内,就可以直接返回我们事先创建好的对象就可以了 。
但是对于Double类型来说,我们就不能这样做,因为它在这个范围内个数是无限的 。
总结一句就是:在某个范围内的整型数值的个数是有限的,而浮点数却不是 。
所以在Double里面的做法很直接,就是直接创建一个对象,所以每次创建的对象都不一样 。
public static Double valueOf(double d) {
return new Double(d);
}
下面我们进行一个归类:
Integer派别:Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的 。
Double派别:Double、Float的valueOf方法的实现是类似的 。每次都返回不同的对象 。
下面对Integer派别进行一个总结,如下图:
下面我们来看看另外一种情况:
public class Main {public static void main(String[] args) {
Boolean i1 = false;
Boolean i2 = false;
Boolean i3 = true;
Boolean i4 = true;
System.out.println(i1==i2);//true
System.out.println(i3==i4);//true
}
}
可以看到返回的都是true,也就是它们执行valueOf返回的都是相同的对象 。
public static Boolean valueOf(boolean b) {
return b ? Boolean.TRUE : Boolean.FALSE;
}
可以看到它并没有创建对象,因为在内部已经提前创建好两个对象,因为它只有两种情况,这样也是为了避免重复创建太多的对象 。
public static final Boolean TRUE = new Boolean(true);
public static final Boolean FALSE = new Boolean(false);
上面把几种情况都介绍到了,下面来进一步讨论其手动拆装箱java代码他情况 。
Integer num1 = 400;
int num2 = 400;
System.out.println(num1 == num2); //true
说明num1 == num2进行了拆箱操作
Integer num1 = 100;
int num2 = 100;
System.out.println(num1.equals(num2));//true
我们先来看看equals源码:
@Override
public boolean equals(Object o) {
return (o instanceof Integer)(((Integer) o).value =https://www.04ip.com/post/= value);
}
我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型 , 所以首先会进行装箱,然后比较,之所以返回true,是由于它比较的是对象里面的value值 。
Integer num1 = 100;
int num2 = 100;
Long num3 = 200l;
System.out.println(num1num2);//200
System.out.println(num3 == (num1num2));//true
System.out.println(num3.equals(num1num2));//false
1、当一个基础数据类型与封装类进行==、 、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算 。
2、对于num3.equals(num1num2)为false的原因很简单,我们还是根据代码实现来说明:
@Override
public boolean equals(Object o) {
return (o instanceof Long)(((Long) o).value =https://www.04ip.com/post/= value);
}
它必须满足两个条件才为true:
1、类型相同
2、内容相同
上面返回false的原因就是类型不同 。
Integer num1 = 100;
Ingeger num2 = 200;
Long num3 = 300l;
System.out.println(num3 == (num1num2)); //true
我们来反编译一些这个class文件:javap -c StringTest
可以看到运算的时候首先对num3进行拆箱(执行num3的longValue得到基础类型为long的值300),然后对num1和mum2进行拆箱(分别执行了num1和num2的intValue得到基础类型为int的值100和200),然后进行相关的基础运算 。
我们来对基础类型进行一个测试:
int num1 = 100;
int num2 = 200;
long mum3 = 300;
System.out.println(num3 == (num1num2)); //true
上面就说明了为什么最上面会返回true.
所以,当 “==”运算符的两个操作数都是 包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程) 。
通过上面的分析我们需要知道两点:
1、什么时候会引发装箱和拆箱
2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存 , 影响性能,所以可以避免装箱的时候应该尽量避免 。
我有一个微信公众号,经常会分享一些Java技术相关的干货文章,还有一些学习资源 。
如果你需要的话,可以用微信搜索“Java团长”或者“javatuanzhang”关注 。
什么是java封装和拆装不太理解你的问题,看到你用封闭和拆装来对应,应该是我下面所说:
java里面有自动装箱和拆装的概念,是对基本数据类型和其封装类的相互转换的描述 。
当基本类型的数据向其封装类转换时,称为自动装箱 。反之,称为拆装 。下面给你一个例子:
Integer a = new Integer(1);
a = a1;//自动装箱
如果不了解这个机制,你会觉得奇怪吧?
int 型的1 竟然可以直接和Integer对象相加?
其实,这就是JVM“自动”先将Integer型的a转化为int型,就是自动拆装
然后,将两个int型号的数据相加
然后装值给转换为Integer的对象,这个就是自动装箱
JAVA从JDK1.5后 , 开始支持这个特性
【手动拆装箱java代码 java拆箱装箱原理】手动拆装箱java代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于java拆箱装箱原理、手动拆装箱java代码的信息别忘了在本站进行查找喔 。

    推荐阅读