Java循环问题

时间:2012-08-07 11:49:50

标签: java for-loop

Object[] objs = new Object[5];
for (int i = 0; i < 5; ++i) {
    int j = i + 1;
    Object obj = objs[i];
}

我对上述循环有两个问题:

  1. 是为每次循环迭代创建了j变量和obj引用,还是只创建了一次,然后才重新分配值?
  2. ++i而不是i++作为增加值的单个指令,是否有任何性能优势?

7 个答案:

答案 0 :(得分:7)

  

是为每个循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?

每次声明和创建

  

将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?

不是。

答案 1 :(得分:6)

  

是为每次循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?

每次循环时,都会创建一个新的int,但obj只是对现有对象的引用,因此不会触发对象创建。无论如何,JVM很可能会为您优化它。

  

将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?

很可能没什么特别的,再一次,JVM可能会改变你的代码。

底线:使用更具可读性的内容,并将变量的范围限制在使用它们的位置。

实际上,JVM可能会将您的代码更改为此,因为您不在循环中使用局部变量:

Object[] objs = new Object[5];
//for (int i = 0; i < 5; ++i) {
//    int j = i + 1;
//    Object obj = objs[i];
//}

答案 2 :(得分:3)

我比较了代码部分的两个字节码。我没有发现什么特别的。唯一的区别是,在第一个样本代码部分中定义了4个局部变量,但在第二个样本代码部分中定义了5个局部变量。但是执行类似的操作码。由于局部变量名称不同,因此执行差异操作码。我的意思是在第一个例子中'我被定义为局部变量-2',在第二个例子中'我被定义为局部变量-4'。

但是通过JVM工具监视代码执行可以提供额外的信息。由于Java是一个平台而JVM可能会优化代码执行,因此我们可能无法通过查看java源代码或java字节码来确定它。

    Object[] objs = new Object[5];  
    for (int i = 0; i < 5; ++i) {  
       int j = i + 1;  
       Object  obj = objs[i];  
    }  

 local-variable-0=this
 local-variable-1=objs
 local-variable-2=i
 local-variable-3=j

  stack=2, locals=5, args_size=1 
 0: aload_0 
 1: invokespecial #8                  // Method java/lang/Object."<init>":()V 
 4: iconst_5 
 5: anewarray     #3                  // class java/lang/Object 
 8: astore_1 #store created object referance to local value-1 (objs)
 9: iconst_0 #push 0 on stack
10: istore_2  # local-value-2(i) assigned 0
11: goto          26 
14: iload_2  #load localvalue 2(i)
15: iconst_1 # ++i operation
16: iadd  #i+1
17: istore_3 #assign i+1 into local-variable-3(j)
18: aload_1 # push object in local varable 1 (objs) onto the stack
19: iload_2 # push integer in local variable 2 (i) onto the stack
20: aaload  # retrieve entry
21: astore        4 # push value on stack into local-variable-4 (obj)
23: iinc          2, 1 # local-variable-2(i)++
26: iload_2 
27: iconst_5 
28: if_icmplt     14 for(if i==5)
31: return 

 **************************************************************************
  Object[] objs = new Object[5];  
    int j; 
    Object obj; 
    for (int i = 0; i < 5; ++i) {  
        j = i + 1;  
        obj = objs[i];  
    }  

  local-variable-0=this
 local-variable-1=objs
 local-variable-2=j
 local-variable-3=obj
 local-variable-4=i

  stack=2, locals=5, args_size=1 
     0: aload_0 
     1: invokespecial #8                  // Method java/lang/Object."<init>":()V 
     4: iconst_5 
     5: anewarray     #3                  // class java/lang/Object 
     8: astore_1 #store created object referance to local value-1 (objs)
     9: iconst_0 #push zero on to the stack
    10: istore        4 # local variable-4(i) is assigned zero
    12: goto          28 
    15: iload         4 
    17: iconst_1 
    18: iadd  #i+1
    19: istore_2  #j is set 
    20: aload_1  #load objs
    21: iload         4 #load i
    23: aaload 
    24: astore_3  #obj=objs[i]
    25: iinc          4, 1 # i++
    28: iload         4 
    30: iconst_5 
    31: if_icmplt     15 # if i==5
    34: return 

答案 3 :(得分:1)

是的,他们是!

这样做:

Object[] objs = new Object[5]; 
int j = 0;
Object obj = new Object();
for (int i = 0; i < 5; ++i) {   
   j = i + 1;   
   obj = objs[i]; 
} 

答案 4 :(得分:1)

是的,他们每次创建,前缀或后缀++无关紧要。

答案 5 :(得分:1)

  

是为每次循环迭代创建了j变量和obj引用,还是只创建了一次,然后只重新赋值?

理论上是的。在实践中,优化代码不会发生。但是,在您的情况下,可能不会优化5(或小于10,000)的循环,因为性能不太重要。

  

将++ i而不是i ++作为单个指令来增加值是否有任何性能优势?

对于优化代码,它们在这里是相同的。对于未经优化的代码,差异不太重要。

答案 6 :(得分:1)

我会尽力回答你的问题......

Are the j variable and obj reference created for every loop iteration or they are created once and then only reassigned the values?

int j每次都创建Object Reference Variable obj每次在循环中也创建,但是 NOT THE OBJECT

Is there any perfomance benefit of putting ++i instead of i++ as a single instruction to increment the value?

如果未分配 j's value则无关紧要。