Java包装类总是让人好奇它和值类型有什么样的关系?本文将以int和Integer为例来探讨它们的关系。Java值类型包括intshortcharbooleanbytelongfloatdouble类型都是引用类型。引用类型和值类型的区别大家都很熟悉。我不会在这里谈论它。引用类型和值类型有一个重要的区别,就是引用类型继承自Object类。值类型不是Java的许多通用容器。两者都要求类型继承自Object,虚方法调用必须是引用类型。显然,这些值类型不满足这个要求。我应该怎么办?包装类应运而生。包装类包括IntegerShortCharBooleanByteLongFloatDouble,对应于上述值类型。由于wrapper类是引用类型,应该传递给其他方法进行修改[url=][/url]publicstaticvoidchange(Integera){a*=6;}publicstaticvoidmain(String[]args){Integer整数=newInteger(5);变化(整数);System.out.println(integer);}[url=][/url]但是上面程序的输出是5,和下面代码的结果是一样的。为什么?[url=][/url]publicstaticvoidchange(inta){a*=6;}publicstaticvoidmain(String[]args){intinteger=5;变化(整数);System.out.println(integer);}[url=][/url]这要从包装类的设计说起。前面说过,包装类是为了弥补值类型的缺陷而设计的。有了wrapper类,整数的表达方式有int和Integer两种。一种是其中一种值类型是引用类型,在使用过程中会给程序员带来麻烦。Java为了消除这个麻烦,在设计的时候尽可能的将它们的不同之处最小化,让包装类表现得像一个值类型,所以出现了上面的结果。这种差异减少是由编译器完成的。如果我们查看编译后的字节码,我们会看到上面的Integer实际上是这样工作的5);变化(整数);System.out.println(integer);}[url=][/url]a*=6的结果返回了一个新的Integer对象,所以无法修改传入的Integer的值即使你想修改Integer类的成员是final的或者不能修改,然后我也发现Object被强制转换为intObjectobj=newInteger(5);inta=(int)obj;编译器处理之后,其实是这样的,也进一步说明了引用类型和值类型完全是两个世界。对象obj=newInteger(5);inta=((Integer)obj).intValue();题外话:对于java值类型和包装类的设计我是很不喜欢java中的一切都是对象值类型,除了同样的整型分为两种,intInteger,感觉没必要。ToString()运行在jvm上的Kotlin有一套特殊的映射规则,可以根据情况自动将Int转化为int和Integer。在语言层面,只有一个IntInta=233;a.toString();但是在java中,你只能这样inta=233;newInteger(a).toString();或inta=233;((Integer)a).toString();参考黑马教程
