实际上here是一个类似的主题,几乎没有实际价值。
据我所知,原语表现更好,应该在任何地方使用,除了需要与对象相关的功能(例如null
检查)的情况。正确?
答案 0 :(得分:23)
不要忘记,因为为每个装箱事件创建一个新的包装器是非常昂贵的,特别是考虑到它通常在方法的单个范围内使用,Autoboxing使用一个公共包装器池。
这实际上是flyweight design pattern的实现。当针对众所周知的值进行装箱时,不是创建新的包装器实例,而是从池中提取预先创建的实例并返回。
一个结果是:仍然不建议使用自动装箱进行科学计算。例如,代码d = a * b + c对a,b,c和d使用Integer类,生成的代码为d.valueOf(a.intValue()* b.intValue()+ c.intValue( ))。所有这些方法调用都有自己的开销,因此通常建议在需要将集合存储在集合中时使用自动装箱。
即便如此,如果你有一个庞大的集合的Integer包装int,那么开销可能意味着更长的执行时间,最多 20倍,因为{{3 }}
Jb补充说:
Wrapper.valueOf(primitive)也使用包装器池。所以更喜欢Integer.valueOf(5)到新的Integer(5)
答案 1 :(得分:10)
原语在使用时速度更快,因为在使用之前需要将对象取消装箱;因此,VM有一个额外的步骤来执行。例如,为了对Integer执行算术运算,必须先将其转换为int才能执行算术。
在许多商业应用中,这可能很少发生。但是,如果你正在编写一些非常重要的东西,比如一个图形转换处理器,你就更有可能关心它。
答案 2 :(得分:5)
是的,原语比对象快。 从java 5开始,您甚至可以混合基元和对象,而无需手动将其转换为另一个。 自动装箱机制就是这样做的。
这意味着如果将一个原语放在一个集合中,编译器就不会抱怨,并隐式地将原语转换为一个对象。
答案 3 :(得分:1)
我会说你应该担心只有当您对应用程序进行概要分析时才使用基元而不是包装器,并且看到自动装箱是性能或内存问题。根据我的经验,在谈论基元与包装对象时,内存在CPU循环之前成为一个问题。
答案 4 :(得分:1)
如果您需要在集合中存储基元,则可以使用commons-primitives。
我更喜欢使用原语来包装,只有绝对需要包装才是实体类的地方。数据库支持空值,因此实体也应该如此。
我曾经参与过在数据库访问中使用原语(和自制ORM)的项目:
class Foo{
int xxx = -1;
...
}
然后你有:
void persist(Foo foo){
...
statement.setInt(15,foo.getXXX()==-1?null:foo.getXXX());
...
}
上帝是邪恶的。