zwbgx04 2011-10-28 17:22
浏览 955
已采纳

关于Java语言for循环内外变量定义的问题

今天被TeamLeader批了一顿,本来想和他争论争论的,后来感觉自己也不清楚,遂只有来Iteye讨教讨教了。
这是个关于在for循环内外变量定义的问题,先看代码:
[code="java"]
public class Test2 {

public static void main(String[] args) {

    // 放入10000000的元素
    List<Object> list = new ArrayList<Object>(10000000);
    for(int i = 0; i < 10000000; i++) {
        list.add(i, new Object());
    }

    // 做10次循环,求均值
    for(int j = 0; j < 10; j++) {

        // 变量在循环内定义
        long t1 = System.currentTimeMillis();
        for(Iterator<Object> iterator = list.iterator(); iterator.hasNext();) {
            Object object = iterator.next();
        }
        long t2 = System.currentTimeMillis();
        System.out.println("循环内" + (j + 1) + "次, 时间:" + (t2 - t1) + ";");

        // 变量在循环外定义
        t1 = System.currentTimeMillis();
        Object object = null;
        for(Iterator<Object> iterator = list.iterator(); iterator.hasNext();) {
            object = iterator.next();
        }
        t2 = System.currentTimeMillis();
        System.out.println("循环外" + (j + 1) + "次, 时间:" + (t2 - t1) + ";");
    }
}

}

/*其中一次的运行结果

  • 变量在循环内定义 变量在循环外定义 *1次循环 359 359 *2次循环 360 343 *3次循环 344 360 *4次循环 359 359 *5次循环 344 359 *6次循环 360 359 *7次循环 360 359 *8次循环 344 359 *9次循环 344 359 *10次循环 344 359 */ [/code]

我在工作中有一段代码是放到循环内定义的,主要是习惯,以及变量最小作用域的理念。但teamleader告诉我要放到循环外面,放在里面性能不好,不太理解。这个问题发生后,我也在网络寻找答案,但结果差不多一半一半,有建议在内部定义,也有建议在外部定义,所以就更糊涂了...我现在所知道的有:在内部定义,满足变量最小作用域的理念,循环外没有使用这个变量,该变量就不会在循环外定义;但teamleader说在内部定义会多次申请栈内存,影响性能,但我写了上面的例子和查了下资料,也没有弄太清这里面是如何影响性能的,请帮助详细讲解下两种定义方式的好坏,及其原因,和jdk版本是否有关系。

  • 写回答

6条回答 默认 最新

  • iteye_6273 2011-11-01 09:49
    关注

    从性能角度而言
    [quote]teamleader说在内部定义会多次申请栈内存,影响性能[/quote],放在循环内部定义,确实会多次申请栈帧的内存空间(java中一个线程对应一个Java栈,每次方法调用会向栈中压入一个新帧,帧中存储着参数、局部变量、中间运算结果等等数据,方法调用结束后当前的帧就被弹出了,可参考我的一篇文章[url]http://boy00fly.iteye.com/blog/1096637[/url]),为什么会多占用栈空间内,原因很简单,每次循环都要重复定义局部变量,而如果放在循环体外,每次只要移动引用指向的堆内存地址即可,不必重新申请内存空间了。
    其实话说回来,这样对性能的影响其实可以忽略不计,没什么大的问题,非要纠结这个性能问题的话,就如我上面说的那样。
    [code="java"]
    public V get(Object key)

    {

    if (key == null)

    return getForNullKey();

    int hash = hash(key.hashCode());

    for (Entry e = table[indexFor(hash, table.length)]; e != null; e = e.next)
    {

    Object k;

    if (e.hash == hash && ((k = e.key) == key || key.equals(k)))

    return e.value;

    }

    return null;

    }

    [/code]
    上面这段代码是jdk中HashMap的源码,你看源码的Object k定义就在循环体内部的! :wink:

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

悬赏问题

  • ¥20 管道轴向耦合水击问题
  • ¥60 补全networkx TODO部分。
  • ¥15 有内推吗,云计算linux运维方向
  • ¥30 sort cuteSV.vcf by bcftools用IGV可视化出现报错
  • ¥100 SOS!对STK中导出的天体图像进行质心提取有没有人做过啊
  • ¥15 python 欧式距离
  • ¥15 运行qteasy报错
  • ¥15 遗传算法解决有工序顺序约束的大规模FJSP问题
  • ¥15 企业消防水炮塔设计方案
  • ¥20 WORKBENCH网格划分