java包装类和值类型的关系

5次阅读

共计 1644 个字符,预计需要花费 5 分钟才能阅读完成。

java 包装类总是让人疑惑 它与值类型到底是怎么样一种关系? 本文将以 int 和 Integer 为例来探讨它们的关系

java 值类型有 int short char boolean byte long float double

除此之外的类型皆为引用类型 引用类型和值类型的区别大家都很熟悉 在这里就不多说了

引用类型和值类型有一个很重要的区别 那就是引用类型继承 Object 类 值类型不是

而 java 很多泛型容器都要求类型继承 Object 调用虚方法要求必须是引用类型 很明显这些值类型不满足这个要求 怎么办? 包装类应运而生

包装类有 Integer Short Char Boolean Byte Long Float Double 和上文的值类型是对应的

既然包装类是引用类型 那么他就应该可以传递到别的方法被修改

[url=][/url]
publicstaticvoidchange(Integer a){a *= 6;}publicstaticvoidmain(String[] args){Integer integer =newInteger(5);    change(integer);    System.out.println(integer);}[url=][/url]

然而 以上程序输出的结果是 5 跟下文代码的结果是相同的 这是为什么?

[url=][/url]
publicstaticvoidchange(inta){a *= 6;}publicstaticvoidmain(String[] args) {intinteger = 5;    change(integer);    System.out.println(integer);}[url=][/url]

这就得从包装类的设计讲起了 前文说过 包装类是为了能够弥补值类型的缺陷而设计的

有了包装类后 对于一个整数的表达就出现了 int 和 Integer 这两个类型 一个是值类型一个是引用类型 这会让程序员在使用过程中产生困扰

为了消除这种困扰 java 在设计时就尽可能地减少它们的区别 让包装类表现得如同值类型 于是就出现了上文的结果

这种区别减少是通过编译器完成 如果我们查看编译好的字节码 就会看到上文的 Integer 其实是这样工作的

[url=]

[/url]
publicstaticvoidchange(Integer a){a = Integer.valueOf(a.intValue() * 6);}publicstaticvoidmain(String[] args){Integer integer =newInteger(5);    change(integer);    System.out.println(integer);}[url=]

[/url]

a*= 6 的结果返回了一个新的 Integer 对象

所以也就不可能修改传入的 Integer 的值了 就算要修改   Integer 这个类的成员是 final 修饰 还是无法修改

然后我还发现了一点 Object 强制转换为 int

Object obj =newInteger(5);inta = (int)obj;

在编译器处理后 其实是这样的 这也进一步说明引用类型和值类型完全是两个世界的东西

Object obj =newInteger(5);inta = ((Integer)obj).intValue();

题外话:

对于 java 的值类型和包装类的设计 我十分不喜欢

java 中一切都是对象 值类型除外

对于同样一个整数类型 分成 int Interger 两个类型感觉很没必要

c# 的 int 是继承 Object 的 在需要调用虚函数的时候会自动装箱

inta =233;a.ToString()

在 jvm 上跑的 Kotlin 它有一套特殊映射法则 把 Int 根据情况自动变换成 int 和 Integer 而在语言层面上只有一个 Int

Int a = 233;a.toString();

但是到了 java 你只能这样

inta = 233;newInteger(a).toString();

或者是这样

inta = 233;((Integer)a).toString();

参考黑马资料教程

正文完
 0