java long 127_java拆箱装箱理解(以Long long为例)

学过Java的同学或多或少都听过自动装箱拆箱,下边通过代码和字节码文件加深下对自动拆箱装箱的理解.

1为什么要有包装类型?

作为和基本数据类型对应的类类型存在,方便涉及到对象的操作,比如泛型必须要求我们是对象数据类型.

2 自动装箱拆箱发生在什么时候?

自动拆箱装箱发生在代码编译期间.

通过例子来看下自动拆箱装箱是怎么做的:

public static void main(String[] args) {

Long a = 100L;

Long b = 100L;

long c = 100L;

Long d = new Long(100);

Long e = 1000L;

Long f = 1000L;

System.out.println(a == b);

System.out.println(a == c);

System.out.println(a == d);

System.out.println(c == d);

System.out.println(e == f);

}

下面先公布答案:

true

true

false

true

false

蒙 a==b为true; 为什么 e==f就是false? a和c是怎么比较的? a和d又是什么情况?

接下来我们通过字节码文件看看到底有什么奥秘:

public static void main(java.lang.String[]);

Code:

0: ldc2_w #2 // long 100l

3: invokestatic #4 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

6: astore_1

7: ldc2_w #2 // long 100l

10: invokestatic #4 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

13: astore_2

14: ldc2_w #2 // long 100l

17: lstore_3

18: new #5 // class java/lang/Long

21: dup

22: ldc2_w #2 // long 100l

25: invokespecial #6 // Method java/lang/Long."":(J)V

28: astore 5

30: ldc2_w #7 // long 1000l

33: invokestatic #4 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

36: astore 6

38: ldc2_w #7 // long 1000l

41: invokestatic #4 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

44: astore 7

46: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;

49: aload_1

50: aload_2

51: if_acmpne 58

54: iconst_1

55: goto 59

58: iconst_0

59: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V

62: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;

65: aload_1

66: invokevirtual #11 // Method java/lang/Long.longValue:()J

69: lload_3

70: lcmp

71: ifne 78

74: iconst_1

75: goto 79

78: iconst_0

79: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V

82: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;

85: aload_1

86: aload 5

88: if_acmpne 95

91: iconst_1

92: goto 96

95: iconst_0

96: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V

99: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;

102: lload_3

103: aload 5

105: invokevirtual #11 // Method java/lang/Long.longValue:()J

108: lcmp

109: ifne 116

112: iconst_1

113: goto 117

116: iconst_0

117: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V

120: getstatic #9 // Field java/lang/System.out:Ljava/io/PrintStream;

123: aload 6

125: aload 7

127: if_acmpne 134

130: iconst_1

131: goto 135

134: iconst_0

135: invokevirtual #10 // Method java/io/PrintStream.println:(Z)V

138: return

}

鬼画符?我们看下这些鬼到底什么意思.

3: invokestatic #4 // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;

意思是执行 Long 的valueof()方法 参数为基本类型 返回值为Long类型

看看Long的valueof方法

public static Long valueOf(long l) {

final int offset = 128;

if (l >= -128 && l <= 127) { // will cache

return LongCache.cache[(int)l + offset];

}

return new Long(l);

}

如果传入的基本类型在-128-127之内就,就从LongCache中取数据返回给我们.看下LongCache干了啥

private static class LongCache {

private LongCache(){}

static final Long cache[] = new Long[-(-128) + 127 + 1];

static {

for(int i = 0; i < cache.length; i++)

cache[i] = new Long(i - 128);

}

}

原来如此,-128-127就直接返回给我们chche中的数据,超出这个范围直接new一个给我们.a==b为true,e==f为false就说得通了.

65: aload_1

66: invokevirtual #11 // Method java/lang/Long.longValue:()J

69: lload_3

70: lcmp

拿出变量a,执行Long.longValue()返回一个基本数据类型,在和c比较.看下longValue方法

/**

* Returns the value of this {@code Long} as a

* {@code long} value.

*/

public long longValue() {

return value;

}

这部就是两个基本数据类型比较吗.

85: aload_1

86: aload 5

88: if_acmpne 95

取出a和d直接比较内存地址是否一样.铁定不一样呀.

剩下的大家可以自己看下,有不明白的可以评论问.

3 总结

自动拆箱装箱没有什么神秘的.字节码可以告诉我们很东西.如果某些概念理解不了,试着看看字节码文件.说不定会豁然开朗.

如果发现文章中有不妥之处,希望大家指出,共同进步.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值