关闭

编写高质量代码:改善Java程序的151个建议(11)

发表于:2012-3-20 09:50

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:秦小波    来源:51Testing软件测试网采编

  建议35:避免在构造函数中初始化其他类

  构造函数是一个类初始化必须执行的代码,它决定着类的初始化效率,如果构造函数比较复杂,而且还关联了其他类,则可能产生意想不到的问题,我们来看如下代码:

  1. public class Client {  
  2.      public static void main(String[] args) {  
  3.           Son s = new Son();  
  4.           s.doSomething();  
  5.      }  
  6. }  
  7. //父类  
  8. class Father{  
  9.      Father(){  
  10.          new Other();  
  11.      }  
  12. }//子类  
  13. class Son extends Father{  
  14.      public void doSomething(){  
  15.         System.out.println("Hi,show me something");  
  16.     }  
  17. }  
  18. //相关类  
  19. class Other{  
  20.      public Other(){  
  21.           new Son();  
  22.     }  
  23. }

  这段代码并不复杂,只是在构造函数中初始化了其他类,想想看这段代码的运行结果是什么?是打印“Hi,show me something”吗?

  答案是这段代码不能运行,报StackOverflowError异常,栈(Stack)内存溢出。这是因为声明s变量时,调用了Son的无参构造函数,JVM又默认调用了父类Father的无参构造函数,接着Father类又初始化了Other类,而Other类又调用了Son类,于是一个死循环就诞生了,直到栈内存被消耗完毕为止。

  可能有读者会觉得这样的场景不可能在开发中出现,那我们来思考这样的场景:Father是由框架提供的,Son类是我们自己编写的扩展代码,而Other类则是框架要求的拦截类(Interceptor类或者Handle类或者Hook方法),再来看看该问题,这种场景不可能出现吗?

  那有读者可能要说了,这种问题只要系统一运行就会发现,不可能对项目产生影响。

  那是因为我们在这里展示的代码比较简单,很容易一眼洞穿,一个项目中的构造函数可不止一两个,类之间的关系也不会这么简单的,要想瞥一眼就能明白是否有缺陷这对所有人员来说都是不可能完成的任务,解决此类问题的最好办法就是:不要在构造函数中声明初始化其他类,养成良好的习惯。

  建议36:使用构造代码块精炼程序

  什么叫代码块(CodeBlock)?用大括号把多行代码封装在一起,形成一个独立的数据体,实现特定算法的代码集合即为代码块,一般来说代码块是不能单独运行的,必须要有运行主体。在Java中一共有四种类型的代码块:

  (1)普通代码块

  就是在方法后面使用“{}”括起来的代码片段,它不能单独执行,必须通过方法名调用执行。

  (2)静态代码块

  在类中使用static修饰,并使用“{}”括起来的代码片段,用于静态变量的初始化或对象创建前的环境初始化。

  (3)同步代码块

  使用synchronized关键字修饰,并使用“{}”括起来的代码片段,它表示同一时间只能有一个线程进入到该方法块中,是一种多线程保护机制。

31/3123>
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号