了解Java的自动装箱与拆箱

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

    //自动装箱

  Integer total = 99;

    //自动拆箱

   int totalprim = total;

需要装箱拆箱的类型有:

Integer total = 99; 
执行上面那句代码的时候,系统为我们执行了: 
Integer total = Integer.valueOf(99);

int totalprim = total; 
执行上面那句代码的时候,系统为我们执行了: 
int totalprim = total.intValue();

对于装箱:

当进行装箱时如果-128<=value<=127时,则会返回已经产生的静态的Inreger数组对象。而其他值则创建一个Integer对象,因此,装箱的过程会创建对应的对象,这个会消耗内存,所以装箱的过程会增加内存的消耗,影响性能。

对于拆箱:直接返回value值给基本数据类型。

二. 相关问题:

上面我们看到在Integer的构造函数中,它分两种情况:

1、i >= 128 || i < -128 =====> new Integer(i)

2、i < 128 && i >= -128 =====> SMALL_VALUES[i + 128]

SMALL_VALUES本来已经被创建好,也就是说在i >= 128 || i < -128是会创建不同的对象,在i < 128 && i >= -128会根据i的值返回已经创建好的指定的对象。

当面对下面的代码时

Integer i1 = 100;

Integer i2 = 100;

Integer i3 = 200;

Integer i4 = 200;

Integer i5=new Integer(100);

Integer i6=new Integer(100);

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

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

  System.out.println(i5==i6);  //false

从上面的例子可以看出i1和i2会进行自动装箱,并且值在SMALL_VALUES数组中,所以会引用到同一个Integer对象中,所以是相等的,而后面i3和i4则是自己各自创建一个新的对象,所以是不等的,对于i5和i6则是自己创建一个对象,不涉及到装箱和拆箱,所以不相等。

注意:SMALL_VALUES数组则是只对Integer、Short、Character、Long中存在,而其他的都是默认创建一个新的对象,当进行比较时都不相等。

对于Boolean类型中,内部已经提前创建好两个对象,所以在进行比较时是相等的。

三.当基本数据类型与包装类型进行比较时会发生什么情况呢?

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

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

总结: 
1、需要知道什么时候会引发装箱和拆箱 
2、装箱操作会创建对象,频繁的装箱操作会消耗许多内存,影响性能,所以可以避免装箱的时候应该尽量避免。

3、equals(Object o) 因为原equals方法中的参数类型是封装类型,所传入的参数类型(a)是原始数据类型,所以会自动对其装箱,反之,会对其进行拆箱

4、当两种不同类型用==比较时,包装器类的需要拆箱, 当同种类型用==比较时,会自动拆箱或者装箱

四.Java 变量参数传入方法,修改后是否影响外面的值

基本类型:值存放在局部变量表中,无论如何修改只会修改当前栈帧的值,方法执行结束对方法外不会做任何改变;此时需要改变外层的变量,必须返回主动赋值。

引用数据类型:指针存放在局部变量表中,调用方法的时候,副本引用压栈,赋值仅改变副本的引用。但是如果直接改变副本引用的值,修改了引用地址的对象,此时方法以外的引用此地址对象当然被修改。(两个引用,同一个地址,任何修改行为2个引用同时生效)

Integer是地址传递,但Integer类中final的value字段,说明一旦Integer类创建之后他的值就不能被修改,例如:

Integer m=new Integer(1);

m=6;

这里的原理是当m引用指向6时,创建了一个新的对象,而m指向了这个新的对象,而这个创建对象的原理是自动装箱原理。

而对于

public static void main(String[] args){

Integer a1 = 5;

updateInteger(a1);

System.out.println(a1);

}

public static void updateInteger(Integer var){

var = 10;

中,则是原理如下所示:当一开始a1和var同时指向5,但是var=10引发自动装箱原理,造成var指向新的对象10,所以对于a1并没有改变值。

关于String,本质是final类型char数组,不可修改,只能赋值,在做参数传入方法修改时,其实是新建对象,必须返回重新对外面的变量赋值才会对外面的String引用生效。

原文地址:https://www.cnblogs.com/xiaobaidashu/p/12096456.html

时间: 2024-11-02 08:27:38

了解Java的自动装箱与拆箱的相关文章

Java的自动装箱和拆箱

1 public class BoxingDemo { 2 3 public static void main(String[] args) { 4 5 /** 6 * 自动装箱示例: 7 * 基本类型int是不能直接赋值给其包装类对象Integer的,但是这里这条语句可以编译通过 8 * 因为自动装箱原理隐式包含了下面2条语句: 9 * Integer temp = new Integer(1); 10 * int1 = temp; 11 * */ 12 Integer int1 = 1; 1

Java中自动装箱与拆箱详解

在讲装箱与拆箱之前我们要先了解一下这个问题的来源: Java中的类型分为基本类型(Primitive type)和类类型(Class type)两种: 基本类型包括byte型.char型.short型.int型.long型.float型.double型.boolean型八种.基本类型指的是直接包含值得类型,可提供语言级别的支持. 类类型包括Byte.Character.Short.Integer.Long.Float.Double.Boolean.为什么要用类类型呢?原因其实很简单,因为Java

Java 包装类 自动装箱和拆箱

包装类(Wrapper Class) 包装类是针对于原生数据类型的包装. 因为有8个原生数据类型,所以对应有8个包装类. 所有的包装类(8个)都位于java.lang下. Java中的8个包装类分别是:Byte, Short, Integer, Long, Float, Double, Character, Boolean,它们的使用方式都是一样的,可以实现原生数据类型与包装类型的双向转换. 下面以主要Integer类为例说明. Integer Integer类将int类型的值包装到一个对象中.

Java的自动装箱和拆箱的简单讲解

 装箱就是把基础类型封装成一个类.比如把int封装成Integer,这时你就不能把他当成一个数了,而是一个类了,对他的操作就需要用它的方法了. 拆箱就是把类转换成基础类型.比如你算个加法什么的是不能用类的,就得把它转换成基本类型,jdk5以后已经可以自动转换了貌似.基本类型你应该懂的吧 (byte,short,int,long,float,double,boolean,char) byte :java.lang.Byte short :java.lang.Short int: java.lang

[转]JAVA自动装箱和拆箱

1.Java数据类型 装箱和拆箱之前,我们先来了解一下Java的基本数据类型. 在Java中,数据类型可以分为两大种,Primitive Type(基本类型)和Reference Type(引用类型).基本类型的数值不是对象,不能调用对象的toString().hashCode().getClass().equals()等方法.所以Java提供了针对每种基本类型的包装类型.如下: Java基本数据类型 INDEX 基本类型  大小 数值范围 默认值 包装类型 1 boolean    --- t

Java基础之包装类的自动装箱和拆箱详解

定义 在java中,数据类型可以分为两大类,即基本数据类型和引用数据类型,基本数据类型的数据不是对象,所以对于要将数据类型作为对象来使用的情况,java提供了相对应的包装类.(关于包装类的详细介绍请参看博客Java基础之常用类详解) 本篇博客主要讲述包装类的自动装箱和拆行机制. 所谓装箱,就是把基本数据类型用它们相对应的引用类型包起来,使它们可以具有对象的特质,如我们可以把int类型包装成Integer类型的对象,或者把double包装秤Double,等等. 所谓拆箱,就是和装箱的方向相反,将I

《Java中的自动装箱和拆箱功能.》

1 //Java中的自动装箱和拆箱功能. 2 class AutoboxingUnboxing 3 { 4 public static void main(String[] args) 5 { 6 //直接把一个基本类型变量赋给Interger对象. 7 Integer inObj = 5; 8 Object inObj1 = 6; 9 //直接把一个boolean类型的变量赋给一个Object类型的变量. 10 Object boolObj = true; 11 //直接把Integer对象赋

java自动装箱与拆箱

基本数据(Primitive)类型的自动装箱(autoboxing).拆箱(unboxing)是J2SE 5.0提供的新功能,跟泛型.变长参数等一样,这也是一颗"语法糖",之前介绍jvm早期优化的时候说过,语法糖对运行期的代码没有任何影响,其目的仅仅是方便程序员使用,所有语法糖编译后都将会还原成基础语法.这次介绍的自动装箱和拆箱也不例外.看下头的例子: public class Demo { public static void main(String[] args) { Intege

Java 自动装箱和拆箱

JDK1.5之后的功能 自动装箱:指的是开发人员可以把一个基本数据类型直接赋给对应的包装类 自动拆箱:指开发人员可以把一个包装类对象直接赋给对应的基本数据类型 public static void main(String[] args) { Integer i = 1; //装箱 int j = i ; //拆箱 } public static void main(String[] args) { List list = new ArrayList(); list.add(1); int j=