Java:在for循环中调用arr.length的次数是多少?

时间:2010-08-20 22:48:24

标签: java

如果arr是一个大小为10的数组,则在以下代码块中,arr.length访问了多少次?

for (int i = 0; i < arr.length; ++i);

在?或者每次循环?

谢谢大家!这就是我最终做的事情:

final int len = arr.length;
for (int i = 0; i < len; ++i);

7 个答案:

答案 0 :(得分:7)

十一次......

10次,声明i < arr.length评估为true 1次评估到false并且循环结束。

答案 1 :(得分:4)

由于允许在循环中更改arr,因此通常在每次评估循环终止条件时对其进行评估。

优化编译器(或JIT)可能会识别出在循环中更改arr,然后只评估arr.length一次。

答案 2 :(得分:3)

没有编译器优化,11次(每次迭代一次+最后一次迭代后一次)。但是编译器会优化这个东西,所以只有一个访问权限。但我所说的假设你的for循环有一个正文:

for (int i = 0; i < arr.length; ++i) {
   ...
}

在你的情况下,循环没有正文:

for (int i = 0; i < arr.length; ++i);

所以这是一个无操作,编译器将删除它。因此,在特定情况下,您将访问该字段零次。

但不要依赖编译器优化,因为你真的不知道它的作用。

答案 3 :(得分:3)

是一个体面的现代vm的可能答案。

在你的特定循环中,因为它没有做任何事情,很可能 vm将完全绕过它。

在以下示例中

size = ...
arr = new byte[size];
for (int i = 0; i < arr.length; ++i)
    non-trivial-statements;

vm可以推导出已经在寄存器中的arr.length == size,因此直接使用size

更有趣的是,知道已经i<arr.length,因此arr[i]不需要运行时绑定检查,使得数组访问与C数组一样便宜。

然而,Java语言没有规定这些东西。一个vm可以访问它零次或一百万次,只要可观察的效果是相同的,它就是正确的。

重点是,你不应该担心它。以共同方式编写的程序很可能需要进行大量优化。跟随人群在这种情况下得到回报。

答案 4 :(得分:1)

每次按定义循环。 如果你幸运,可能会优化为1。

答案 5 :(得分:0)

(int i=0, n=arr.length; i<n; i++);

是一个简单的习惯用语,既不是

  • a)依赖于编译器或
  • b)需要非循环范围的变量 保持长度,
  • c)只评估arr.length一次

答案 6 :(得分:0)

你也可以做一些像

这样的实验
public class Count{

    private static int count; 

    private static int getLength(Object[] arr) {
        count += 1;
        return arr.length;
    }

    public static void main(String[] args){
        count = 0;
        Object[] arr = new Object[10];
        for (int i = 0; i < getLength(arr); ++i) {
            // do something
        }
        System.out.printf("called %d times%n", count);
    }
}    

有关详细信息,还会打印i的值和getLength的返回值(或使用调试器)。

要进行快速在线测试,请查看Youjavaitideone