问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

java拆箱装箱原理(至关工委的一封感谢信)

发布网友 发布时间:2024-10-02 20:48

我来回答

1个回答

热心网友 时间:2024-10-19 13:37

JAVA自动包装的详解

◆什么是自动包装?

自动包装,又称自动封装,即把基础数据类型(如int)转换成基础派咐搏类型封装类的对象(如newInteger())

拆箱就是装箱的反过程,即把基础类型封装类的对象(如newInteger())转换为基础数据类简哪型(如int)。

装箱:Integera=newInteger();

a=100;//1.5以前不支持为对象如此赋值

拆箱:intb=newInteger(100);

◆为什么要自动封装?

1、因为封装的数据类型就是一个对象,可以拥有属性和方法,有了这些属性和方法,我们就可以用它们来处理数据.比如Integer对象里的parseInt(Strings),可以把字符串转换成int类型等

2、java是面向对象的一门语言,到处都是对象,有些时候我们需要传递的值必须是对象类型的.比如:structs框架里的DynaActionForm,当JSP页面数据传到dform中时,我们需要(Integer)dform.get("qty");,而(int)dform.get("qty");这样是错误的.

◆尘祥8种基本数据类型及其封装类

.type.Class

booleanBoolean

byteByte

charCharacter

doubleDouble

floatFloat

intInteger

longLong

shortShort

java什么时候触发装箱和拆箱

最近面试也遇到了这个问高派题,思考总结了一肢念圆下。

装箱:在基本类型的值赋值给包装类型时触发。历塌例如:Integera=1;

这时二进制文件中实际上是Integera=Integer.valueOf(1);

拆箱:

1.在包装类型赋值给基本类型时触发。

例如:Integera=1;?//a是Integer类型

intb=a;?//将Integer类型赋值给int类型,触发拆箱

2.在做运算符运算时触发。

例如:

Integera=1;

Integerb=2;

System.out.print(a*b);//这时a*b在二进制文件中被编译成a.intValue()*b.intValue();

注意点:

==运算时,如果a和b都是Integer类型,则不会拆箱,因为==也可以直接比较对象,表示a和b是否指向同一对象地址。因此这里并不是比较值是否相等了。而如果a和b中有一个是int类型,另一个是Integer类型,则会触发拆箱,然后对两个int值进行比较。

Integera=128;

Integerb=128;

Integerc=127;

Integerd=127;

System.out.print(a==b);//返回false

System.out.print(c==d);//返回true

原因是Integer的装箱(Integer.valueOf())方法会自动缓存-128~127之间的值,多次装箱同一个值实际上用的是同一个对象,因此这里a==b是false,因为不是同一个对象,而c==d是true,因为使用缓存中的同一个对象,而不是因为值相等。

Integera=127;

Integere=newInteger(127);

Integerf?=Integer.intValue(127);

System.out.println(a==e);//返回false,不是同一个对象

System.out.println(a==f);//返回true,是缓存中同一个对象

欢迎修改补充...

什么是java中的自动装箱和自动拆箱

java自动装箱和拆箱

基本数据类型,如int,float,double,boolean,char,byte,不具备对象的特征,不能调用世如锋方法。

装箱:将基本类型转换成包装类对象

inti=10;

Integerx=newInteger(i);手动装箱

Integery=10;自动装箱

拆箱:将包装类对象转换成基本类型的值

Integerj=newInteger(8);

intm=j.intValue();//手动拆箱

intn=j;//自动拆箱

java为什么要引入自动装箱和拆箱的功能?又是怎么实现的呢?

主要是用于java集合中,ListInteterlist=newArrayListInteger();

list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象。

实现原理:javac编译器的语法糖

publicclassMain{

publicstaticvoidmain(String[]args){

Integeri1=100;

Integeri2=100;

Integeri3=200;

Integeri4=200;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:truefalse

在通过Integer.valueOf()方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用(位于堆对象池中);否则创建一个新的Integer对象(创建在java堆中)。上搜晌面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

publicclassMain{

publicstaticvoidmain(String[]args){

Doublei1=100.0;

Doublei2=100.0;

Doublei3=200.0;

Doublei4=200.0;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:falsefalse

为什么Double类的valueOf方法会采用橡丛与Integer类的valueOf方法不同的实现呢?很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

publicclassMain{

publicstaticvoidmain(String[]args){

Booleani1=false;

Booleani2=false;

Booleani3=true;

Booleani4=true;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:truetrue

至于为什么是这个结果,同样地,看了Boolean类的源码也会一目了然。下面是Boolean的valueOf方法的具体实现:

publicstaticBooleanvalueOf(booleanb){

return(b?TRUE:FALSE);

}

publicclassH{

publicstaticvoidmain(String[]args){

Integerm=10;

intn=10;

System.out.println(m==n);

}

}

//结果为:true

java什么是拆箱和装箱,拆箱和装箱嘛用啊???

详解Java的自动装箱与拆箱(Autoboxingandunboxing)

一、什么是自动装箱拆箱?

很简单,下面两句代码就可以看到装箱和拆箱过程

//自动装橡此箱

Integer?total?=?99;

//自定拆箱

int?totalprim?=?total;

简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

下面我们来看看需要装箱拆箱的类型有哪些:

这个过程是自动执行的,那么我们需要看看它的执行过程:

public?class?Main?{

????public?static?void?main(String[]?args)?{

????//自动装箱

????Integer?total?=?99;

????//自定拆箱

????int?totalprim?=?total;

????}

}

反编译class文件之后得到如下内容:

javap?告卜-c?StringTest

Integertotal=99;?

执行上面那句代码的时候,系统为我们执行了:?

Integertotal=Integer.valueOf(99);

inttotalprim=total;?

执行上面那句代码的时候,系统为我们执行了:?

inttotalprim=total.intValue();

我们现在就以Integer为例,来分析一下它的源码:?

1、首先来看看Integer.valueOf函数

public?static?Integer?valueOf(int?i)?{

????return??i?=?128?||?i??-128???new?Integer(i)?:?SMALL_VALUES[i?+?128];

}

它会首先判断i的大小:如果i小于-128或者大于等于128,就创建一个Integer对象,否则执行SMALL_VALUES[i+128]。

首先我们来看看Integer的构造函数:

private?final?int?value;

public?Integer(int?value)?{

????this.value?=?value;

}

public?Integer(String?string)?throws?NumberFormatException?{

????this(parseInt(string));

}

它里面定义了一个value变量,创建一个Integer对象,就会给这个变量初始化。第二个传入的是一个String变量,它会先把它转换成一个int值,然后进行初始化。

下面看看SMALL_VALUES[i+128]是什么东西:

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=====newInteger(i)?

2、i128i=-128=====SMALL_VALUES[i+128]

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,所以会执行newInteger(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);

上面把几种情况都介绍到了,下面来进一步讨论其他情况。

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?==?value);

}

我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会进行装箱,然后比较,之所以返回true,是由于它比较的是对象里面的value值。

Integer?num1?=?100;??

int?num2?=?100;??

Long?num3?=?200l;??

System.out.println(num1?+?num2);??//200

System.out.println(num3?==?(num1?+?num2));??//true

System.out.println(num3.equals(num1?+?num2));??//false

1、当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。?

2、对于num3.equals(num1+num2)为false的原因很简单,我们还是根据代码实现来说明:

@Override

public?boolean?equals(Object?o)?{

????return?(o?instanceof?Long)??(((Long)?o).value?==?value);

}

它必须满足两个条件才为true:?

1、类型相同?

2、内容相同?

上面返回false的原因就是类型不同。

Integer?num1?=?100;

Ingeger?num2?=?200;

Long?num3?=?300l;

System.out.println(num3?==?(num1?+?num2));?//true

我们来反编译一些这个class文件:javap-cStringTest?

可以看到运算的时候首先对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?==?(num1?+?num2));?//true

上面就说明了为什么最上面会返回true.

所以,当“==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

通过上面的分析我们需要知道两点:?

1、什么时候会引发装箱和拆箱?

2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

我有一个微信公众号,经常会分享一些Java技术相关的干货文章,还有一些学习资源。

如果你需要的话,可以用微信搜索“Java团长”或者“javatuanzhang”关注。

什么是Java自动拆装箱?

自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之清肢就是自答渗世动拆喊悉箱。

什么是java封装和拆装

不太理解你的问题,看到你用封闭和拆装来对应,应该是我下面所说:

java里面有自动装箱和拆装的概念,是对基本数据类型和其封装类的相互转换的描述。

当基本类型的

热心网友 时间:2024-10-19 13:35

JAVA自动包装的详解

◆什么是自动包装?

自动包装,又称自动封装,即把基础数据类型(如int)转换成基础派咐搏类型封装类的对象(如newInteger())

拆箱就是装箱的反过程,即把基础类型封装类的对象(如newInteger())转换为基础数据类简哪型(如int)。

装箱:Integera=newInteger();

a=100;//1.5以前不支持为对象如此赋值

拆箱:intb=newInteger(100);

◆为什么要自动封装?

1、因为封装的数据类型就是一个对象,可以拥有属性和方法,有了这些属性和方法,我们就可以用它们来处理数据.比如Integer对象里的parseInt(Strings),可以把字符串转换成int类型等

2、java是面向对象的一门语言,到处都是对象,有些时候我们需要传递的值必须是对象类型的.比如:structs框架里的DynaActionForm,当JSP页面数据传到dform中时,我们需要(Integer)dform.get("qty");,而(int)dform.get("qty");这样是错误的.

◆尘祥8种基本数据类型及其封装类

.type.Class

booleanBoolean

byteByte

charCharacter

doubleDouble

floatFloat

intInteger

longLong

shortShort

java什么时候触发装箱和拆箱

最近面试也遇到了这个问高派题,思考总结了一肢念圆下。

装箱:在基本类型的值赋值给包装类型时触发。历塌例如:Integera=1;

这时二进制文件中实际上是Integera=Integer.valueOf(1);

拆箱:

1.在包装类型赋值给基本类型时触发。

例如:Integera=1;?//a是Integer类型

intb=a;?//将Integer类型赋值给int类型,触发拆箱

2.在做运算符运算时触发。

例如:

Integera=1;

Integerb=2;

System.out.print(a*b);//这时a*b在二进制文件中被编译成a.intValue()*b.intValue();

注意点:

==运算时,如果a和b都是Integer类型,则不会拆箱,因为==也可以直接比较对象,表示a和b是否指向同一对象地址。因此这里并不是比较值是否相等了。而如果a和b中有一个是int类型,另一个是Integer类型,则会触发拆箱,然后对两个int值进行比较。

Integera=128;

Integerb=128;

Integerc=127;

Integerd=127;

System.out.print(a==b);//返回false

System.out.print(c==d);//返回true

原因是Integer的装箱(Integer.valueOf())方法会自动缓存-128~127之间的值,多次装箱同一个值实际上用的是同一个对象,因此这里a==b是false,因为不是同一个对象,而c==d是true,因为使用缓存中的同一个对象,而不是因为值相等。

Integera=127;

Integere=newInteger(127);

Integerf?=Integer.intValue(127);

System.out.println(a==e);//返回false,不是同一个对象

System.out.println(a==f);//返回true,是缓存中同一个对象

欢迎修改补充...

什么是java中的自动装箱和自动拆箱

java自动装箱和拆箱

基本数据类型,如int,float,double,boolean,char,byte,不具备对象的特征,不能调用世如锋方法。

装箱:将基本类型转换成包装类对象

inti=10;

Integerx=newInteger(i);手动装箱

Integery=10;自动装箱

拆箱:将包装类对象转换成基本类型的值

Integerj=newInteger(8);

intm=j.intValue();//手动拆箱

intn=j;//自动拆箱

java为什么要引入自动装箱和拆箱的功能?又是怎么实现的呢?

主要是用于java集合中,ListInteterlist=newArrayListInteger();

list集合如果要放整数的话,只能放对象,不能放基本类型,因此需要将整数自动装箱成对象。

实现原理:javac编译器的语法糖

publicclassMain{

publicstaticvoidmain(String[]args){

Integeri1=100;

Integeri2=100;

Integeri3=200;

Integeri4=200;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:truefalse

在通过Integer.valueOf()方法创建Integer对象的时候,如果数值在[-128,127]之间,便返回指向IntegerCache.cache中已经存在的对象的引用(位于堆对象池中);否则创建一个新的Integer对象(创建在java堆中)。上搜晌面的代码中i1和i2的数值为100,因此会直接从cache中取已经存在的对象,所以i1和i2指向的是同一个对象,而i3和i4则是分别指向不同的对象。

publicclassMain{

publicstaticvoidmain(String[]args){

Doublei1=100.0;

Doublei2=100.0;

Doublei3=200.0;

Doublei4=200.0;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:falsefalse

为什么Double类的valueOf方法会采用橡丛与Integer类的valueOf方法不同的实现呢?很简单:在某个范围内的整型数值的个数是有限的,而浮点数却不是。

publicclassMain{

publicstaticvoidmain(String[]args){

Booleani1=false;

Booleani2=false;

Booleani3=true;

Booleani4=true;

System.out.println(i1==i2);

System.out.println(i3==i4);

}

}

//结果为:truetrue

至于为什么是这个结果,同样地,看了Boolean类的源码也会一目了然。下面是Boolean的valueOf方法的具体实现:

publicstaticBooleanvalueOf(booleanb){

return(b?TRUE:FALSE);

}

publicclassH{

publicstaticvoidmain(String[]args){

Integerm=10;

intn=10;

System.out.println(m==n);

}

}

//结果为:true

java什么是拆箱和装箱,拆箱和装箱嘛用啊???

详解Java的自动装箱与拆箱(Autoboxingandunboxing)

一、什么是自动装箱拆箱?

很简单,下面两句代码就可以看到装箱和拆箱过程

//自动装橡此箱

Integer?total?=?99;

//自定拆箱

int?totalprim?=?total;

简单一点说,装箱就是自动将基本数据类型转换为包装器类型;拆箱就是自动将包装器类型转换为基本数据类型。

下面我们来看看需要装箱拆箱的类型有哪些:

这个过程是自动执行的,那么我们需要看看它的执行过程:

public?class?Main?{

????public?static?void?main(String[]?args)?{

????//自动装箱

????Integer?total?=?99;

????//自定拆箱

????int?totalprim?=?total;

????}

}

反编译class文件之后得到如下内容:

javap?告卜-c?StringTest

Integertotal=99;?

执行上面那句代码的时候,系统为我们执行了:?

Integertotal=Integer.valueOf(99);

inttotalprim=total;?

执行上面那句代码的时候,系统为我们执行了:?

inttotalprim=total.intValue();

我们现在就以Integer为例,来分析一下它的源码:?

1、首先来看看Integer.valueOf函数

public?static?Integer?valueOf(int?i)?{

????return??i?=?128?||?i??-128???new?Integer(i)?:?SMALL_VALUES[i?+?128];

}

它会首先判断i的大小:如果i小于-128或者大于等于128,就创建一个Integer对象,否则执行SMALL_VALUES[i+128]。

首先我们来看看Integer的构造函数:

private?final?int?value;

public?Integer(int?value)?{

????this.value?=?value;

}

public?Integer(String?string)?throws?NumberFormatException?{

????this(parseInt(string));

}

它里面定义了一个value变量,创建一个Integer对象,就会给这个变量初始化。第二个传入的是一个String变量,它会先把它转换成一个int值,然后进行初始化。

下面看看SMALL_VALUES[i+128]是什么东西:

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=====newInteger(i)?

2、i128i=-128=====SMALL_VALUES[i+128]

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,所以会执行newInteger(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);

上面把几种情况都介绍到了,下面来进一步讨论其他情况。

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?==?value);

}

我们指定equal比较的是内容本身,并且我们也可以看到equal的参数是一个Object对象,我们传入的是一个int类型,所以首先会进行装箱,然后比较,之所以返回true,是由于它比较的是对象里面的value值。

Integer?num1?=?100;??

int?num2?=?100;??

Long?num3?=?200l;??

System.out.println(num1?+?num2);??//200

System.out.println(num3?==?(num1?+?num2));??//true

System.out.println(num3.equals(num1?+?num2));??//false

1、当一个基础数据类型与封装类进行==、+、-、*、/运算时,会将封装类进行拆箱,对基础数据类型进行运算。?

2、对于num3.equals(num1+num2)为false的原因很简单,我们还是根据代码实现来说明:

@Override

public?boolean?equals(Object?o)?{

????return?(o?instanceof?Long)??(((Long)?o).value?==?value);

}

它必须满足两个条件才为true:?

1、类型相同?

2、内容相同?

上面返回false的原因就是类型不同。

Integer?num1?=?100;

Ingeger?num2?=?200;

Long?num3?=?300l;

System.out.println(num3?==?(num1?+?num2));?//true

我们来反编译一些这个class文件:javap-cStringTest?

可以看到运算的时候首先对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?==?(num1?+?num2));?//true

上面就说明了为什么最上面会返回true.

所以,当“==”运算符的两个操作数都是包装器类型的引用,则是比较指向的是否是同一个对象,而如果其中有一个操作数是表达式(即包含算术运算)则比较的是数值(即会触发自动拆箱的过程)。

通过上面的分析我们需要知道两点:?

1、什么时候会引发装箱和拆箱?

2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

我有一个微信公众号,经常会分享一些Java技术相关的干货文章,还有一些学习资源。

如果你需要的话,可以用微信搜索“Java团长”或者“javatuanzhang”关注。

什么是Java自动拆装箱?

自动装箱是Java编译器在基本数据类型和对应的对象包装类型之间做的一个转化。比如:把int转化成Integer,double转化成double,等等。反之清肢就是自答渗世动拆喊悉箱。

什么是java封装和拆装

不太理解你的问题,看到你用封闭和拆装来对应,应该是我下面所说:

java里面有自动装箱和拆装的概念,是对基本数据类型和其封装类的相互转换的描述。

当基本类型的

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
vivo y18l 死机卡在开机界面 vivoy18l手机频繁黑屏死机怎么办? vivo y18l 死机了怎么办 vivoY18l黑屏死机解决办法 vivo y18l刷机很久都开不了机怎么? 湖北自考专升本会有学籍吗? 湖北自考专升本后可以考研吗 湖北自考申请毕业证的时间在什么时候 湖北自考专升本学历怎么查询 湖北自考专升本为什么没有学籍 我现在初中,如果我想学护士专业,请问我毕业以后应该去上什么学校? 什么叫场景 我是初中毕业现在想报名学护士专业能行吗? int i=5,k; k=(++i)+(++i)+(++i); cout<<k<<endl; 为什么运行后k是22... 2024欧洲杯什么时候开始 男生送我千多的玉佩是喜欢我吗 男生送女生兔子玉佩代表什么 我用qq 加她的微信,请问怎么能找到她的手机号??? ...别人用手机登的QQ(微信) 能不能通过它QQ(微信)知道他的手机号... 我想通过微信号找一个人的手机号或者qq号,怎么办?哪位大神可以帮我... 月饼为什么要回油 月饼的制作过程怎么写 ai重新着色选项是灰色的ai重新着色选项是灰色的怎么回事 冰皮月饼糊为什么要静置30分钟 ...灰色怎么改ai里面颜色模式默认灰色怎么改成白色 ai怎么把灰色底去掉ai怎么把图变成灰色 做月饼的面为什么要醒一到二小时 缩阴提肛运动练习方法 苍山马先蒿形态特征 量一量,填一填. 测量的物体 我的估计 我的测量 我的长 我的厚 我... C++中i=3时的(++i)+(++i)+(++i)的值为什么等于16呢,为什么不是15?求解... 影评分析中结构、人物、场景是什么? 有一部电视剧是说一个女老师教那些学生,但那些学生都很喜欢打架的,这个... 如何分析电影的画面、声音、剪辑? 求几部校园打架的电影,狼的诱惑 那小子真帅 火山高校 热血高校都看过了... 阿城附近的山,景点旅游推荐阿城 ...只过了一科综合素质,现在报考高中体育教资能不能直接报教育知识与能... 有一个日本电影一个女生受到老师和同学的欺负 电影最后的时候她的同... 天谕手游海上寻宝任务宝藏在哪 海上寻宝任务宝箱坐标分享-新手攻略-安... 生完宝宝后脸上长痘怎么办 天谕手游梦中的宝藏怎么做_梦中的宝藏完成方法介绍 天谕手游苏澜寻宝汐海怎么做 在哪里能找到宝藏位置 天谕手游海上寻宝梁先生在哪海上寻宝梁先生坐标详情一览 苹果手机怎么去掉话筒符号显示? 轴承坏了是什么原因造成的 有关百分数的成语 顺便写上qq账号及qq名 谢谢 中国古代九大力王,武松第8,鲁智深第3,第1无人能及 中国古代九大力王,武松第8,鲁智深第3,第1无人能及 装修时环保就能保证无毒吗?有没有无毒的装修材料啊? 环保漆刷新家多久适合人们居住,请看华豹公司为您解析