原始类型与原始类型打包原始类型
主要区别
身份与身份价值:
原语:它们没有身份;具有相同值的两个基元始终相等。
打包:它们是对象并且有一个标识;两个对象可以具有相同的值但不同的标识。
空值:
基元: 始终有一个默认值(例如,int 为 0)。
Packed: 可能为 null,如果处理不当可能会导致 NullPointerException 异常。
表现:
原语:在时间和空间上更高效。
打包: 由于创建额外对象而引入开销。
混合基元和包时的常见问题
有问题的示例:
ComparatornaturalOrder = (i, j) -> (i 问题: 比较 i == j 比较引用,而不是值。
不正确的行为:naturalOrder.compare(new Integer(42), new Integer(42)) 返回 1 而不是 0。解决方案:
使用 Integer.
类的 CompareTo 方法或实用程序方法ComparatornaturalOrder = Integer::compare; 或者,修正原来的比较器:
ComparatornaturalOrder = (iBoxed, jBoxed) -> { int i = iBoxed; int j = jBoxed; return (i 2.自动拆箱和 NullPointerException
当使用可以为 null 的打包类型时,如果对象为 null,自动拆箱可能会引发异常。有问题的示例:
Integer i = null; if (i == 42) { System.out.println("Inacreditável"); }问题: i 为空;与 42 比较时,发生 null 自动拆箱,导致 NullPointerException.
解决方案:尽可能使用原始类型。int i = 0; if (i == 42) { System.out.println("Inacreditável"); }3.由于自动装箱/拆箱导致性能下降
在密集型操作中无意中使用包装类型可能会由于自动装箱和不必要的对象创建而导致性能下降。有问题的示例:
Long sum = 0L; for (long i = 0; i问题: sum 是一个压缩的 Long;在每次迭代中,都会发生自动装箱/拆箱。
影响:代码速度慢得多,内存使用量过多。
解决方案:
在密集操作中使用局部变量的原始类型。Long sum = 0L; for (long i = 0; i何时使用封装类型
- 集合:不能在泛型集合中使用原始类型(例如列表)。
- 泛型参数:泛型类型不支持原始类型(例如ThreadLocal)。
- 需要对象的 API:某些 API 需要对象而不是原始类型。
良好实践
- 首选原始类型:只要有可能,就使用原始类型以实现简单性和效率。
- 谨防自动装箱/拆箱:自动装箱可减少冗长,但可能会引入微妙的错误。
- 避免在 Wrapped 中与 == 进行比较:使用 equals() 等方法或比较展开的值。
- 检查空值:使用封装类型时,请注意它们可能为空并导致 NullPointerException。
概括
原始类型:
更简单、更快。
它们不能为空。
他们没有身份(只有价值)。打包类型:
需要在集合和通用 API 中使用。
它们可以为空。
他们有对象标识。
免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。
Copyright© 2022 湘ICP备2022001581号-3