如果arr
是一个大小为10的数组,则在以下代码块中,arr.length
访问了多少次?
for (int i = 0; i < arr.length; ++i);
在?或者每次循环?
谢谢大家!这就是我最终做的事情:
final int len = arr.length;
for (int i = 0; i < len; ++i);
答案 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++);
的是一个简单的习惯用语,既不是
答案 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
的返回值(或使用调试器)。