Autoboxing and Autounboxing

前言:

  • 首先我们要知道Java中有哪些基本数据类型以及它们各自的封装类:package java.lang;
基本数据类型封装类
byteByte
booleanBoolean
charCharacter
shortShort
intInteger
longLong
floatFloat
doubleDouble

一、什么是Autoboxing

java中Autoboxing是指将基本数据类型自动转换成封装类类型。比如说:

1
2
3
4
5
6
7
8
9
public void test1()
{
int a = 10;
Integer b = a;
System.out.println(b);

Character d = 'c';
System.out.println(d);
}
  • 函数参数为封装类类型时,调用时传递基本数据类型,会发生Autoboxing。
  • 将基本数据类型变量赋值给封装类类型时,会发生Autoboxing。

二、什么是Autounboxing

java中Autounboxing是指将封装类类型自动转换成基本数据类型。比如说:

1
2
3
4
5
6
7
8
9
10
public void test2()
{
Integer a = new Integer(10);
int b = a;
System.out.println(b);

Character c = 'c';
char d = c;
System.out.println(d);
}
  • 函数参数为基本数据类型,调用时传递封装类类型,会发生Autounboxing。
  • 将封装类类型变量赋值给基本数据类型,或者直接用封装类类型进行基本运算,会发生Autounboxing。

三、以int类型为例,讲解Autoboxing和Autounboxing实现原理

先来看一段代码反汇编的结果

  • java代码
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    package com.sh.$16.$12.$22;
    /**
    * Created by Mr SJL on 2016/12/22.
    *
    * @Author Junlan Shuai
    */

    import java.util.ArrayList;
    import java.util.List;

    public class App1
    {
    public static void main(String[] args)
    {
    Integer integer = 10;
    int i = integer;
    }

    }
  • 反汇编结果
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    public class com.sh.$16.$12.$22.App1 {
    public com.sh.$16.$12.$22.App1();
    Code:
    0: aload_0
    1: invokespecial #1 // Method java/lang/Object."<init>":()V
    4: return

    public static void main(java.lang.String[]);
    Code:
    0: bipush 10
    2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
    5: astore_1
    6: aload_1
    7: invokevirtual #3 // Method java/lang/Integer.intValue:()I
    10: istore_2
    11: return
    }

从以上java代码可以看出,“Integer integer = 10;”此句发生了Autoboxing。

从汇编结果可以看出,实际在编译的时候发生了,Integer a = Integer.valueOf(10);调用了Integer类的valueOf方法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

从以上java代码可以看出,“int i = integer;”此句发生了Autounboxing。

从汇编结果可以看出,实际在编译的时候发生了,int i = integer.intValue();调用了Integer类的intValue方法。

1
2
3
4
5
6
7
/**
* Returns the value of this {@code Integer} as an
* {@code int}.
*/
public int intValue() {
return value;
}

四、总结

其他基本数据类型的Autoboxing and Autounboxing也满足此。


思考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.sh.$16.$12.$24;

/**
* Created by Mr SJL on 2016/12/24.
*
* @Author Junlan Shuai
*/
public class App2
{
public static void main(String[] args)
{
int a = 10;
int b = 10;
Integer c = new Integer(10);
Integer d = Integer.valueOf(10);
Integer e = 2000;
Integer f = 2000;

System.out.println("a=b:" +(a==b));
System.out.println("a=c:" +(a==c));
System.out.println("a=d:" +(a==d));
System.out.println("c=d:" +(c==d));
System.out.println("e=f:" +(e==f));
}
}

// 运行结果:
a=b:true
a=c:true
a=d:true
c=d:false
e=f:false

Comments

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×