使用哪个,int 还是 Integer?

77

我需要创建一个数据传输对象,用于存储从数据库检索出的记录。在此数据传输对象中,我需要声明一个数字字段。对于这个字段,哪个更好 - int 还是 Integer

如果我将字段定义为 Integer,那么如果我要从数据库检索超过 2000 条记录,是否会因为 'Integer' 类型而有任何性能影响!?

提前致谢。


你很可能会发现,从数据库将数据物理移动到程序中的开销会压倒整数包装器的性能影响。 - Thorbjørn Ravn Andersen
我猜这也会有所帮助:https://softwareengineering.stackexchange.com/questions/203970/when-to-use-primitive-vs-class-in-java - Visrut
11个回答

148

Integer是一个更好的选择,因为它可以处理null;对于int,如果使用resultSet.getInt(..)null会在不知不觉中变成0。否则,它可能会抛出一些异常,比如“无法将null设置为原始属性”。

性能在这里并不重要。

  • 如果选择int,您最终将添加额外的处理代码; 这不会给您带来太多好处。您的代码将不会清晰明了,有很多样板代码,而且您甚至不会获得性能提升。
  • 让我明确一下,对于数据库,null和零不同。有时候,您会输入0,而本意是想输入null。想象一下用户提交表单,没有为int提供任何值的情况。你最终会默认得到0。当该字段在数据库中不是not null时,这是有意义的,或者说真的有意义吗。

1
Adeel,我认为你应该编辑你的答案,把你评论中的信息包含进去。它们与这个讨论相关,可能会被一些只是浏览答案的人所忽略。 - William Brendel
11
@Adeel: 空值如何悄无声息地变成0? - Miserable Variable
@ William Brendel。我将我的评论包含在原始帖子中。谢谢。 - Adeel Ansari
1
有关null<->int问题和其他ORM问题的更多信息,请查看阻抗不匹配 - tddmonkey
getInt(int) 返回一个整数 - null 已经被静默地转换为 0。相反,您应该在 DAO 中使用 isNull() 来检查可空列,然后根据需要在模型中使用 null 整数或魔术数字 (-1)。 - JeeBee
显示剩余2条评论

26

在做决策时,应该基于对象需要完成的任务来选择,而不是性能成本。只有通过分析工具(profiler)检测到速度问题后,才应该以性能为基础作出决策。

比较两者的特点并根据需要做出决策,例如:

  • Integer 可以为 null,但 int 不行。那么数据库中的 int 字段是一个 Nullable 字段吗?
  • 是否需要访问 Integer 类方法?
  • 是否需要进行算术运算?

个人而言,我总是更喜欢使用原始类型,而非包装类。但这只是一种偏好,而非基于技术优势做出的决策。


自动装箱会处理它,如果它只发生一次的话。否则,在执行任何重型计算之前,请将其转换。 - Adeel Ansari
真的,但如果你在多个计算中使用点操作符,你可能想选择int选项以避免多次强制转换。 - tddmonkey

12

在我看来,将某个变量声明为int或Integer的选择仅仅取决于它是否允许为null。自动装箱和拆箱会处理任何需要将数字强制转换为一个特定类型的情况。在几乎所有情况下,性能也不太可能有明显的差异。

此外,int应该是自然的选择,并且如果性能成为问题,那么很可能是最高效的选择。如果您需要能够存储null值,则必须使用Integer(并确保不要将空引用自动拆箱为只接受int的方法,否则将导致NullPointerException)。


5

Integer理论上比int慢,但是除非你在进行大量计算,否则性能影响应该很小。此外,JIT优化将减少性能损失。

根据原始类型或引用类型的情况,选择更适合您情况的一个。


4

int 比 integer 快 10 倍

我们使用 jetm 性能库对此代码进行测试

int n;
EtmPoint point1 = etmMonitor.createPoint("test:objects");
for (n = 0; n < 1000000; n++) {
    Integer t = 0;
    t = 10;
    t = 11;
}

point1.collect();
EtmPoint point = etmMonitor.createPoint("test:primitives");
for (n = 0; n < 1000000; n++) {
    int t = 0;
    t = 10;
    t = 11;
}
point.collect();

etmMonitor.render(new SimpleTextRenderer());

以下是结果:
测试:对象 10.184
测试:基元 1.151


6
int的速度比其他类型快很多,但是即使在你的例子中,你也要进行一百万次迭代才能看出差别。请尝试仅使用2000个值,因为提问者将只使用这么多。此外,你应该首先测试你认为最快的选项,以避免受到未预热的JVM产生的影响。 - Peter Lawrey
将测试从Integer转换为int或2000个项目将产生相同的结果。 int比Integer更快。请记住,Integer是一个类,上面的代码可以翻译为C ++,如下所示:for(n = 0; n <2000; n ++){Integer * t = new Integer(0); t-> privateJVMSetValue(10); t-> privateJVMSetValue(11);}当然,对象可以为null。如果需要,确实不应使用int。 - Ratata Tata
1
这个基准测试太小、太简单了,根本无法展示任何东西。虽然这并不代表什么,但在添加预热轮后,我得到了以下时间:整数循环:0.0018秒,int循环:0.0020秒。可能大部分循环中发生的事情都被优化掉了。 - Lii

2

int 是 Java 最常用的计算类型。除了原始数组,Integer 在所有集合形式中都被使用。

大量使用临时 Integer 会导致垃圾收集器负荷过重,并在后台使用无法进行性能分析的 CPU,从而导致整体减速。每秒垃圾回收的临时对象过多会导致 CG 进入紧急“我需要现在释放内存”的模式,这可能会导致延迟关键型应用(如实时交互式图形、物理设备控制器或通信)出现停顿。

对我来说,如果有很多嵌套调用,不涉及数学计算但却访问了许多集合(例如使用映射的键),我会使用 Integer,以避免传递参数时自动装箱过多。

如果操作是数学密集型或用作循环计数器或其他面向数学的操作,并且不存储在集合中(除了原始数组),我则使用原始数据类型。对于除了字符串之外的所有原始数据类型也是如此,因为字符串是一个完整的对象。


2
给你一个想法,2000个整数会为您的查询添加约0.5毫秒。如果您必须对此数据进行序列化,它可能会增加更多时间。
然而,正确性应该放在第一位。非常快但错误没有意义。您必须考虑null值及其处理方式(除非列是NOT NULL)。您可以使用Integer.MIN_VALUE或者使用long字段代替int并使用Long.MIN_VALUE来表示null。即使它比int大,它仍然比Integer小得多且更高效。

1

我猜这取决于你用什么来访问数据库。使用普通的JDBC,你可以使用int,而ORM可能会将它们悄悄地转换为Integers。而Integer则允许你处理nulls


0

int 无法使用 toString(String) 转换为 String

Integer 可以使用 toString(String) 转换为 String,并且可以处理 null


1
您可以使用 String.valueOf(int)int 转换为 String。正如@Adeel的答案所指出的那样,能够处理 'null' 是这里唯一的优势。 - Marcelo
1
我不确定你在使用什么奇怪的编译器,但你永远不能将一个整数强制转换为字符串。 - tddmonkey

0
如果您想检查一个null值,那么使用Integer是最好的选择,但如果您想比较整数,则int可能更好。在下面的示例中,我使用整数c=1000和d=1000进行比较,返回false,但在int的情况下,它们将返回true。
public class IntegerCompare {

    public static void main(String[] args) {
        int a = 1000;
        int b = 1000;

        Integer c = 1000;
        Integer d = 1000;

        if (a == b) {
            System.out.println("int Value Equals");

        }
        if (c == d) {
            System.out.println("Integer value Equals");

        } else {

            System.out.println("Integer Value Not Equals");
        }
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接