请教一个java编码规范的问题?

悬赏:5 发布时间:2008-07-23 提问人:bigbird (初级程序员)

公司的java编码规范对于如下写法:
for(int i=0;i<personId.length;i++){
SignUpByCourseVO vo = new SignUpByCourseVO();
......
}
要求这么写:
SignUpByCourseVO vo=null;
for(int i=0;i<personId.length;i++){
vo = new SignUpByCourseVO();
......
}

我不是很理解具体有什么不同,因为无论vo在循环外,还是循环内定义,都是要在循环内初始化的,第一种写法会有性能问题吗?
请哪位帮解答一下?多谢!


问题补充:
多谢你的解答。还是有个疑问,两种实现效率上没什么差别,那在内存的使用上有没有差别呢,第一种写法每次循环时都会创建一个vo引用吧?这样如果数据量大时,是不是就有内存上的差异了,也就是说第一种比第二种更耗内存?
该问题已经关闭: 感谢各位解答,本人不是想深究什么技术东西,只是有些疑惑,想知道个为什么。毕竟网络上藏龙卧虎。

回答

从语句上分析,循环外创建效率会比循环内创建效率高,但是现在编译器有优化功能,这种情况,两种写法经过优化后字节码应该是一样的,也就是说,优化编译后,执行效率一样。
从作用域来讲,后一种往往比较好,把对象作用于限制在循环体内,避免其污染循环体外。
sunsong (初级程序员) 2008-07-23
package com.sss.test.String;

public class TestLoop {
public   void   test1(){  
  String   str;  
  for(int   i=0;i<100;i++){  
    str= new String("hello");  
  System.out.println(str);  
  }  
   
  }  
   
  public   void   test2(){  
   
  for(int   i=0;i<100;i++){  
  String   str=new String("hello");  
  System.out.println(str);  
  }  
   
  }  
}编译该类,然后在命令行中位于相应目录使用javap -verbose TestLoop得到字节码,对比一下:
public void test1();
  Code:
   Stack=3, Locals=3, Args_size=1
   0: iconst_0
   1: istore_2
   2: goto 25
   5: new #15; //class java/lang/String
   8: dup
   9: ldc #17; //String hello
   11: invokespecial #19; //Method java/lang/String."<init>":(Ljava/lang/String;)V
   14: astore_1
   15: getstatic #22; //Field java/lang/System.out:Ljava/io/PrintStream;
   18: aload_1
   19: invokevirtual #28; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   22: iinc 2, 1
   25: iload_2
   26: bipush 100
   28: if_icmplt 5
   31: return
  LineNumberTable:
   line 6: 0
   line 7: 5
   line 8: 15
   line 6: 22
   line 11: 31
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      32      0    this       Lcom/sss/test/String/TestLoop;
   15      10      1    str       Ljava/lang/String;
   2      29      2    i       I
===============================================================
public void test2();
  Code:
   Stack=3, Locals=3, Args_size=1
   0: iconst_0
   1: istore_1
   2: goto 25
   5: new #15; //class java/lang/String
   8: dup
   9: ldc #17; //String hello
   11: invokespecial #19; //Method java/lang/String."<init>":(Ljava/lang/String;)V
   14: astore_2
   15: getstatic #22; //Field java/lang/System.out:Ljava/io/PrintStream;
   18: aload_2
   19: invokevirtual #28; //Method java/io/PrintStream.println:(Ljava/lang/String;)V
   22: iinc 1, 1
   25: iload_1
   26: bipush 100
   28: if_icmplt 5
   31: return
  LineNumberTable:
   line 15: 0
   line 16: 5
   line 17: 15
   line 15: 22
   line 20: 31
  LocalVariableTable:
   Start  Length  Slot  Name   Signature
   0      32      0    this       Lcom/sss/test/String/TestLoop;
   2      29      1    i       I
   15      7      2    str       Ljava/lang/String;


除了LocalVariableTable中变量顺序不一样,执行逻辑上没有区别。
说明编译器已经进行了优化(我的环境是jdk1.5)

基于上述实验,我认为采用第二种写法更好。
sunsong (初级程序员) 2008-07-23
public class Test {
	static String s = "sssssssssssssssssssssssssssssss";
	static {
		System.out.println(s);
	}

	public static void main(String[] args) {
		Long startTime = System.currentTimeMillis();
		Test test = null;
		for (int i = 0; i < 1000000; i++) {
			test = new Test();
		}
		Long endTime = System.currentTimeMillis() - startTime;
		System.gc();
		Long startTime2 = System.currentTimeMillis();
		for (int j = 0; j < 1000000; j++) {
			Test test2 = new Test();
		}
		Long endTime2 = System.currentTimeMillis() - startTime2;
		System.out.println(endTime2);
		System.out.println(endTime);
	}

}


前面的效率比后面的高 test下
visoin (中级程序员) 2008-07-23
做了个试验,两种不同的写法,产生的class目标文件是不同的,第一种方法产生的class文件体积稍大。分别对两个class文件进行反编译,获得的源文件与最初的源文件完全一样。由此,我怀疑编译器没有对这种情况进行优化,但这只是猜测。

将符号声明写在循环内,与写在循环外面相比,会有部分额外的开销,在循环次数不是巨大的情况下,我认为对性能的影响可以忽略不计的。

所以,要求写在循环外声明类变量符号,主要还是出于性能的考虑。
qdzheng (中级程序员) 2008-07-23
to visoin :
你把1000000修改一下看看,在不同数量级效果不一样。具体原因尚未得知
可参看csdn相关讨论
http://topic.csdn.net/t/20060627/15/4846244.html
sunsong (初级程序员) 2008-07-23
我认为第一种好,容易懂。

如果没有足够的理由,没必要用第二种。

新手不需要考虑这样的问题,公司让怎么写就怎么写,很多时候就是某个老大的习惯而已,这种问题没什么意义。

像String和StringBuffer哪个更好,这样的问题也不要去想,爱用哪个用拿个。
性能,不是由这些东西影响的。
王者之剑 (初级程序员) 2008-07-24