热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Java中Integer与int类型的装箱和拆箱

其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。我们分四种情况来讨论:

        其实Integer与int类型的赋值与比较最关键的一点就是:这两个变量的类型不同。Integer是引用类型,int是原生数据类型。
        我们分四种情况来讨论:
        1) Integer与int类型的赋值
                a.把Integer类型赋值给int类型。此时,int类型变量的值会自动装箱成Integer类型,然后赋给Integer类型的引用,这里底层就是通过调用valueOf()这个方法来实现所谓的装箱的。
                b.把int类型赋值给Integer类型。此时,Integer类型变量的值会自动拆箱成int类型,然后赋给int类型的变量,这里底层则是通过调用intValue()方法来实现所谓的拆箱的。
        2) Integer与int类型的比较
                这里就无所谓是谁与谁比较了,Integer == int与int == Integer的效果是一样的,都会把Integer类型变量拆箱成int类型,然后进行比较,相等则返回true,否则返回false。同样,拆箱调用的还是intValue()方法。
        3) Integer之间的比较
                这个就相对简单了,直接把两个引用的值(即是存储目标数据的那个地址)进行比较就行了,不用再拆箱、装箱什么的。
        4) int之间的比较
                这个也一样,直接把两个变量的值进行比较。
        值得注意的是:对Integer对象,JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存。底层代码如下:

    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127;
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

        测试代码如下:

public class IntegerAndIntTest
{
	public static void main(String[] args) throws Exception
	{
		Integer a = 127, b = 128;
		
		int c = 128;
		
		//自动装箱,这里会调用Integer中的valueOf方法把c装箱成Integer类型
		a = c;
		
		//这里比较的是两个对象的地址,显然不等
		System.out.println(a == b);
		
		//这里会调用Integer的intValue方法获得Integer对象a指向的栈地址中存的值再与c进行值比较,
		//而不是把c装箱成Integer类型进行地址比较
		System.out.println(a == c);
		
		//同上,也是获得a指向的栈地址中存的值
		System.out.println(c == a);
		
		/**
		 * 总结:只有在赋值(=)的时候才会出现装箱和拆箱两种情况,
		 * 在比较(==)的时候只会出现一种情况,那就是拆箱,而不会出现装箱的情况
		 */
		System.out.println("----------------------------------");
		
		Integer i1 = 127;
		Integer i2 = 127;
		
		System.err.println(i1 == i2);
		i1 = 128;
		i2 = 128;
		System.err.println(i1 == i2);
		
		/**
		 * 总结:JVM会自动缓存-128~127范围内的值,所以所有在这个范围内的值相等的Integer对象都会共用一块内存,而不会开辟多个;
		 * 超出这个范围内的值对应的Integer对象有多少个就开辟多少个内存,这样做是为了节省内存消耗。
		 */
	}
}

        反编译结果:具体看第2、9、22、27、38、72、92、116、123、149、157等行,这几行涉及到装箱、拆箱。

  public static void main(java.lang.String[]) throws java.lang.Exception;
    flags: ACC_PUBLIC, ACC_STATIC
    Exceptions:
      throws java.lang.Exception
    Code:
      stack=3, locals=7, args_size=1
         0: bipush        127
         2: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
         5: astore_1
         6: sipush        128
         9: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        12: astore_2
        13: sipush        128
        16: istore_3
        17: bipush        127
        19: istore        4
        21: iload_3
        22: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
        25: astore_1
        26: aload_1
        27: invokevirtual #25                 // Method java/lang/Integer.intVal
ue:()I
        30: istore        4
        32: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
        35: iload         4
        37: aload_1
        38: invokevirtual #25                 // Method java/lang/Integer.intVal
ue:()I
        41: if_icmpne     48
        44: iconst_1
        45: goto          49
        48: iconst_0
        49: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
        52: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
        55: aload_1
        56: aload_2
        57: if_acmpne     64
        60: iconst_1
        61: goto          65
        64: iconst_0
        65: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
        68: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
        71: aload_1
        72: invokevirtual #25                 // Method java/lang/Integer.intVal
ue:()I
        75: iload_3
        76: if_icmpne     83
        79: iconst_1
        80: goto          84
        83: iconst_0
        84: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
        87: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
        90: iload_3
        91: aload_1
        92: invokevirtual #25                 // Method java/lang/Integer.intVal
ue:()I
        95: if_icmpne     102
        98: iconst_1
        99: goto          103
       102: iconst_0
       103: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
       106: getstatic     #29                 // Field java/lang/System.out:Ljav
a/io/PrintStream;
       109: ldc           #41                 // String ------------------------
----------
       111: invokevirtual #43                 // Method java/io/PrintStream.prin
tln:(Ljava/lang/String;)V
       114: bipush        127
       116: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
       119: astore        5
       121: bipush        127
       123: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
       126: astore        6
       128: getstatic     #46                 // Field java/lang/System.err:Ljav
a/io/PrintStream;
       131: aload         5
       133: aload         6
       135: if_acmpne     142
       138: iconst_1
       139: goto          143
       142: iconst_0
       143: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
       146: sipush        128
       149: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
       152: astore        5
       154: sipush        128
       157: invokestatic  #19                 // Method java/lang/Integer.valueO
f:(I)Ljava/lang/Integer;
       160: astore        6
       162: getstatic     #46                 // Field java/lang/System.err:Ljav
a/io/PrintStream;
       165: aload         5
       167: aload         6
       169: if_acmpne     176
       172: iconst_1
       173: goto          177
       176: iconst_0
       177: invokevirtual #35                 // Method java/io/PrintStream.prin
tln:(Z)V
       180: return



推荐阅读
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文讨论了使用差分约束系统求解House Man跳跃问题的思路与方法。给定一组不同高度,要求从最低点跳跃到最高点,每次跳跃的距离不超过D,并且不能改变给定的顺序。通过建立差分约束系统,将问题转化为图的建立和查询距离的问题。文章详细介绍了建立约束条件的方法,并使用SPFA算法判环并输出结果。同时还讨论了建边方向和跳跃顺序的关系。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 本文介绍了一个Java猜拳小游戏的代码,通过使用Scanner类获取用户输入的拳的数字,并随机生成计算机的拳,然后判断胜负。该游戏可以选择剪刀、石头、布三种拳,通过比较两者的拳来决定胜负。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • JavaSE笔试题-接口、抽象类、多态等问题解答
    本文解答了JavaSE笔试题中关于接口、抽象类、多态等问题。包括Math类的取整数方法、接口是否可继承、抽象类是否可实现接口、抽象类是否可继承具体类、抽象类中是否可以有静态main方法等问题。同时介绍了面向对象的特征,以及Java中实现多态的机制。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • Java 11相对于Java 8,OptaPlanner性能提升有多大?
    本文通过基准测试比较了Java 11和Java 8对OptaPlanner的性能提升。测试结果表明,在相同的硬件环境下,Java 11相对于Java 8在垃圾回收方面表现更好,从而提升了OptaPlanner的性能。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文介绍了在Android开发中使用软引用和弱引用的应用。如果一个对象只具有软引用,那么只有在内存不够的情况下才会被回收,可以用来实现内存敏感的高速缓存;而如果一个对象只具有弱引用,不管内存是否足够,都会被垃圾回收器回收。软引用和弱引用还可以与引用队列联合使用,当被引用的对象被回收时,会将引用加入到关联的引用队列中。软引用和弱引用的根本区别在于生命周期的长短,弱引用的对象可能随时被回收,而软引用的对象只有在内存不够时才会被回收。 ... [详细]
author-avatar
dsvsV
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有