工具软件   办公软件   操作系统   网络安全   设计在线   程序开发   教程宝典   软件下载   软件论坛
您的位置:软件 > 开发者网络 > 程序人生 > 正文
全世界所有程序员都会犯的错误
[文章信息]
作者:chensheng913
时间:2004-07-16
出处:论坛
责任编辑:方舟
[文章导读]
不管使用何种语言,全世界所有程序员都一定犯过这种错误,那就是:太依赖编译器,却不知道编译器做了哪些事
advertisement
热点推荐
· Java加密和数字签名编程快速入门
· 在VB6中用命令行为模式控制GUI动作
· Excel图表向导详解
· 浅析各种计算机病毒应对方法
· 2月16日软件精选 春节文章精彩回顾
[正文]

1 2  下一页

  当年,国际巨星成龙的“龙种”曝光,众人指责他对不起娇妻林凤娇,逼得他出面召开记者会,向世人自白他犯了“全世界所有男人都会犯的错误”。从来没犯过这种错误的我,也因此常常认为自己不是个男人。

  虽然没犯过“全世界所有男人都会犯的错误”,但是我倒是曾经犯了“全世界所有程序员都会犯的错误”。不管使用何种语言,全世界所有程序员都一定犯过这种错误,那就是:太依赖编译器,却不知道编译器做了哪些事。

  一般来说,越高阶的程序语言,会提供越多语法上的便利,以方便程序撰写,这就俗称为syntactic sugar,我称其为“语法上的甜头”。虽说是甜头,但是如果你未能了解该语法的实质内涵,很可能会未尝甜头,却吃尽苦头。

  不久前,我收到一个电子邮件,读者列出下面的Java程序,向我求救。看过这个程序之后,我确定这又是一个“全世界所有程序员都会犯的错误”。

// 程序1

class Singleton
{
 private static Singleton obj = new Singleton();
 public static int counter1;
 public static int counter2 = 0;
 private Singleton()
 {
  counter1++;
  counter2++;
 }
 public static Singleton getInstance()
 {
  return obj;
 }
}

// 程序2

public class MyMain
{
 public static void main(String[] args)
 {
  Singleton obj = Singleton.getInstance();
  System.out.println("obj.counter1=="+obj.counter1);
  System.out.println("obj.counter2=="+obj.counter2);
 }
}

  执行结果是:

  obj.counter1==1
  obj.counter2==0

  你有没有被此结果吓一跳?乍看程序代码,你很可能会认为counter1和counter2的值一定会相等,但执行结果显然不是如此。其实,程序1被编译后的程序应该等同于下面的程序3:

// 程序3
class Singleton
{
 private static Singleton obj;
 public static int counter1;
 public static int counter2;
 static
 {
  // 这就是class constructor
  // 在进入此class constructor之前,class已经被JVM
  // 配置好内存,所有的static field都会被先设定为0,
  // 所以此时counter1和counter2都已经是0,且singleton为null
  obj = new Singleton();
  // 问题皆由此行程序产生
  // counter1不会在此被设定为0
  counter2 = 0;
  // counter2再被设定一次0(其实是多此一举)
 }
 private Singleton()
 {
  // 这是instance constructor
  counter1++;
  counter2++;
 }

 public static Singleton getInstance()
 {
  return obj;
 }
}

  这是因为:当class具有static field,且直接在宣告处透过“=...”的方式设定其值时,编译器会自动将这些叙述依序搬到class constructor内。同样地,当class具有instance field,且直接在宣告处透过“=...”的方式设定其值时,编译器会自动将这些叙述依序搬到instance constructor内。

  此程序在class constructor内,还未将static field初始化时(这时候,counter1和counter2都是0),就呼叫instance constructor,而instance constructor竟然还会去更动static field的值,使得counter1和counter2都变成1。然后instance constructor执行完,回到class constructor,再把counter2的值设为0(但是counter1维持不变)。最后的结果:counter1等于1,counter2等于0。

1 2  下一页

天极社区邀请您:写博客日记  上传相片   论坛聊天  订阅电子杂志  推荐网摘   免费图铃工具
笔名:   请您注意:

 遵守国家有关法律、法规,尊重网上道德,承担一切因您的行为而直接或间接引起的法律责任。

 天极网拥有管理笔名和留言的一切权利。
评论:
 
发表评论推荐给朋友我想参加相关培训打印我对此感兴趣订阅电子杂志
相关内容焦点新闻
  • 中兴携手阿尔卡特 全球逐鹿CDMA
  • 用友总裁王文京:誓将ERP变成“大众消费”
  • 香港消费者委员会:数码相机最贵未必最好
  • 外电称中兴正评估西门子手机业务 或能并购
  • 国信办督战八大行业灾难备份 将出台国家标准
  • 中国IT企业走进欧盟 搭第六框架计划直通车
  • 美邦银行用户注意 警惕新型“钓鱼”邮件
  • 微软三年时间磨出新IE 具有更强大安全性能
  • Advertisement

    天极无线


    奇妙科幻|美好风光|清风车影|漫画卡通|星座生肖|明星写真|动物世界
    老鼠爱大米
    挥着翅膀的女孩
    女人味
    栀子花开
    白月光
    刚刚好
    江南
    快乐崇拜
    亲爱的你怎么不在我身边
    小薇
    2002年的第一场雪
    有多少爱可以重来
    我的地盘
    七里香
    情人
     
    老鼠爱大米 老板电话
    冲动的惩罚 七里香
    我不是黄蓉 女生撒娇
    盛夏的果实 坚持到底
    孤单北半球 眉飞色舞
    挪威的森林 可爱女人
    最浪漫的事 老板电话

    CSEEK搜索