什么时候我应该去原始类型的包装类?或者在什么情况下我应该在包装器/原始类型之间进行选择?
其他人已经提到某些结构如Collections
需要对象,并且该对象比其原始对应物(内存和装箱)具有更多的开销。
另一个考虑是:
将对象初始化为null
或将null
参数发送到方法/构造函数以指示状态或函数可能很方便。这不能用原语来完成。
许多程序员将数字初始化为0(默认值)或-1表示这一点,但根据情况,这可能是错误的或误导性的。
当错误地使用某些东西时,这也将设置NullPointerException
的场景,这比一些任意的bug更加程序员友好。
Java中的原始值不是对象。为了将这些值作为对象进行操作,java.lang包为每个基本数据类型提供了一个包装类。
所有Wrapper课程都是最终的。可以实例化的所有包装类的对象都是不可变的,这意味着无法更改包装器对象中的值。
虽然,void类被认为是一个包装类,但它不包装任何原始值,并且不会无法满足。它没有公共构造函数,它只表示一个表示关键字void的类对象。
通常,除非出于某种原因需要对象(例如放入集合),否则应使用基本类型。即便如此,如果您想要最大化数字性能,请考虑不需要对象的不同方法。这是由the documentation建议的,this article演示了自动装箱如何导致大的性能差异。
在我看来,如果我的类成员是包装变量,它不依赖于默认值,这是开发人员友好的行为。
1.
class Person {
int SSN ; // gets initialized to zero by default
}
2.
class PersonBetter {
Integer SSN; //gets initialized to null by default
}
在第一种情况下,您无法保持SSN值未初始化。如果您在尝试使用之前未检查该值是否已设置,则可能会受到影响。
在第二种情况下,您可以使用null初始化SSN。这可能会导致NullPointerException,但是只要您尝试在不初始化SSN字段的情况下使用它而无意中将默认值(零)作为SSN插入到数据库中。
如果必须,我只会使用包装器类型。
在使用它们时,除了事实上它们是Objects
之外,你并没有获得太多收益。
而且,你会减少内存使用的开销和装箱/拆箱所花费的时间。
集合是简单Java包装器对象的典型案例。但是,您可以考虑在代码(值对象)中赋予Wrapper更具体的含义。
恕我直言,当它归结为代码的可读性和维护时,使用值对象几乎总是有益的。在具有特定职责的对象内部包装简单数据结构通常可以简化代码。这在Domain-Driven Design非常重要。
当然存在性能问题,但我倾向于忽略它,直到我有可能用适当的数据来衡量性能并对问题区域做更多的定向操作。如果代码也易于理解,也可能更容易理解性能问题。
由数值计算主导的应用程序的性能可以从原语的使用中受益匪浅。
原始类型,一个使用==运算符,但对于包装器,首选的选择是调用equals()方法。
"Primitive types considered harmful"因为他们将“程序语义”混合到另外统一的面向对象模型中。
许多程序员将数字初始化为0(默认值)或-1表示这一点,但根据情况,这可能是错误的或误导性的。
实际上我遇到过可以解释使用包装类的情况。
我创建了一个具有long
类型变量的服务类
long
- 未初始化时,它将被设置为0 - 当在GUI中显示时,这将使用户感到困惑Long
- 未初始化时,将设置为null
- 此空值不会显示在GUI中。这适用于Boolean
,当我们使用原始boolean
时值可能更混乱(默认值为false)。
如果要创建值类型。类似产品或机场代码的东西。
当基本类型(我的示例中的字符串)定义相等时,您将希望覆盖相等性。
如果要使用集合,则必须使用Wrapper类。
原始类型用于数组。此外,表示没有行为的数据,例如计数器或布尔条件。
自从自动装箱以来,“何时使用原始或包装”边界变得非常模糊。
但请记住,Wrappers是对象,因此您可以获得所有精美的Java功能。例如,您可以使用reflexion来创建Integer对象,但不能使用int值。包装类也有诸如valueOf之类的方法。