我什么时候应该使用原语而不是包装对象?

实际上这是一个类似的主题,几乎没有实际价值。 据我所知,原语表现更好,应该在任何地方使用,除了需要与对象相关的function(例如null检查)的情况。 对?

不要忘记,因为为每个装箱事件创建一个新的包装器是非常昂贵的,特别是考虑到它通常在方法的单个范围内使用, Autoboxing使用一个常见的包装器池。

这实际上是flyweight设计模式的实现 。 当针对众所周知的值进行装箱时,不是创建新的包装器实例,而是从池中提取预先创建的实例并返回。

其结果之一是: 仍然不建议使用自动装箱进行科学计算 。 例如,代码d = a * b + c使用a,b,c和d的Integer类,生成的代码是d.valueOf(a.intValue()* b.intValue()+ c.intValue( ))。 所有这些方法调用都有自己的开销,因此通常建议在需要时使用自动装箱来存储集合中的基元

即便如此,如果你有一个庞大的Integer包装int 集合 ,那么开销可能意味着更长的执行时间,长达20倍 ,如本文所述 。


Jb补充说这个重要的评论:

Wrapper.valueOf(primitive)也使用包装器池。 所以更喜欢Integer.valueOf(5)到new Integer(5)

使用时原始图形更快,因为在使用之前需要将对象取消装箱; 因此,VM有一个额外的步骤来执行。 例如,为了对Integer执行算术,必须先将其转换为int,然后才能执行算术运算。

在许多商业应用中,这可能很少发生。 但是如果你正在写一些非常重要的东西,比如一个图形转换处理器,那你就更容易关心。

是的,原语比对象快。 从java 5开始,您甚至可以混合基元和对象,而无需手动将其转换为另一个。 自动装箱机制可以解决这个问题。

这意味着如果将基元放在集合中,编译器就不会抱怨,并隐式地将基元转换为对象。

如果您需要在集合中存储基元,则可以使用commons-primitives 。

我更喜欢使用原语来包装,只有绝对需要包装才是实体类的地方。 数据库支持空值,因此实体也应该如此。

我曾经研究过在数据库访问中使用原语(和自制ORM)的项目:

  class Foo{ int xxx = -1; ... } 

然后你有:

  void persist(Foo foo){ ... statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX()); ... } 

上帝是邪恶的。

我会说你应该担心只有当你分析你的应用程序并且看到自动装箱是性能或内存问题时才使用原语而不是包装器。 根据我的经验,在讨论基元与包装对象时,在CPU循环之前,内存成为一个问题。