热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

从C/C++与Java的语言设计看代码质量问题

历代编程语言演化,都尝试着去解决不同的附属性困难问题。从Java反省C++的诸般问题而进行改良的结果,我们可以看出它所尝试要解决的问题的困难。Java中有一个很重大的特色,就是垃圾收集机制(GarbageCollection,GC)。垃圾收集机制允许程序设计者尽管放心的去配置所需的内存空间,而毋需自行处理这些内存空间的

历代编程语言演化,都尝试着去解决不同的附属性困难问题。从Java反省C++的诸般问题而进行改良的结果,我们可以看出它所尝试要解决的问题的困难。

为什么Java要采用垃圾收集机制?

Java中有一个很重大的特色,就是垃圾收集机制(Garbage Collection,GC)。垃圾收集机制允许程序设计者尽管放心的去配置所需的内存空间,而毋需自行处理这些内存空间的释放问题,因为垃圾收集器(Garbage Collector)会自动判断已经不被程序所使用的内存空间,并且自动释放。

惯用C/C++程序语言的程序设计者都知道,自己配置的内存必须自己妥善释放,无论是没有释放或是重复释放,都会造成程序的Bug。程序设计者自己配置内存、自己释放是一种程序设计模型,而只管配置、不管释放,又是另一种程序设计模型。

Java继承了C/C++的血统,却选择了另外一种截然不同处理内存配置与释放的程序设计模型,为什么呢?在Java问世之前,垃圾收集机制已经存在,但鲜少看到十分主流的程序语言采用,原因就是在于它的效能问题。因为自动判断每一块内存区块是否该被回收及加以回收,都需要不少计算量,因而影响到程序的效能。而Java发明者决心以效能换得这个垃圾收集机制,是一个重大的决定,为什么呢?这自然是因为让程序设计者自己配置内存、自己释放的程序设计模型,存在着影响深远的问题,容易滋生出Bug。

从指针与数组来看C/C++

除了内存配置与释放的问题之外,还有许多问题长期以来困扰着C/C++的程序设计者,例如指针的问题。

指针是C/C++中十分具有威力的语法元素,运用指针可以达到许多神奇的效果,也能写出相当优雅的程序代码。指针的运用,可以说是C/C++语言中的一门艺术。但是不幸的,水能载舟亦能覆舟,指针相较于内存配置与释放的问题,更是容易成为Bug的温床。相信有足够C/C++经验的程序设计者,都能理解指标的误用、错用,十分容易引发程序的Bug,而且相当不易察觉。指针允许你指向内存的任意位置,但是一旦指向不属于应用程序可存取的内存地址范围、或是以不正确的方式解读所指向内存中的数据,就会引发严重的错误。

而数组的越位存取也是和指针类似的问题,这一类的问题,甚至可以被刻意操作,衍生成为缓冲区溢位攻击。这类的问题,只要有过足够C/C++程序设计经验的程序设计者,应当都能体会这些在程序设计过程中所可能造成的困扰。它们不仅容易造成Bug,而且所长出来的Bug有很高的比例,都会藏在程序中最隐晦的角落,让你难以发觉。

效果强与易犯错之间如何取舍?

C/C++的程序设计者在内存处理的动作上,得到极为高度的自由,但又吃尽苦头。C/C++在内存处理的程序设计模型很有威力,却也容易让程序设计者犯错,而且一旦犯了错,程序设计者必须花费数倍、甚至数十倍撰写出该错误的心力和时间,才能揪出这个错误并加以修正。这当然是一个值得思考的问题,我们是否要在一个语言中,放入一个极有威力、却容易造成程序设计者犯错的程序模型?

显然Java的发明者选择不这么做,他宁可放弃有威力的武器,也不希望这个武器在伤敌的同时,也同样伤到自己。

而这也反映Java语言在众多面向上的设计哲学,宁可削除一些看似弹性、看似有威力的语法元素,也要换取降低程序设计者因而犯错的机会。所以,Java才会得到一个 “C++ --“ 的评语。身为一个后继、流着相同血源的程序语言,却试图削减,可以想见其中一定充满着许多的反省。

所以,我们可以看见Java中取消了指针,改用参照(reference)来指向对象,没有指针指向任意内存地址的能力。一旦程序设计者做了越界的数组操作,Java的虚拟机器就会掷出异常,并且不允许执行该操作。同样的,程序设计者也无法对指向null的空参照值进行存取,一样会受到虚拟机器的控管,掷出对应的异常对象,待应用程序处理。

从生产力来看,质量才是关键

上述这几个例子,都是传统C/C++程序设计容易犯错的地方,Java从语言的根本上尝试杜绝这几类问题的发生。这些在语言上的设计,也都反映Java的基本哲学──减少程序设计者犯错的机会。

为什么Java这么重视这件事?因为如此才能大大提升软件开发时的生产力。事实上的确如此,正如前段所提的,一旦写下了一个错误,就必须花费数倍、甚至数十倍撰写出该错误的心力和时间,才能揪出这个错误并加以修正。你可以想象,这样开发对生产力会有多大的影响。

花多少时间写下程序代码或许是生产力的关键之一,但是,总共花多少时间得到足够质量的程序代码,才是最后所展现出来的真正生产力指针。我们可以说,Java是把生产力当做最高指导原则之一的程序语言,而它想要得到生产力的重要途径之一,就是在语言层次上尽量避免程序设计者犯错。

C和C++这两个语言中,存在不少容易让程序设计者犯错的地方,这是Java之所以要C加加之后再减减的原因。

举例来说:

int a = 3; 
int b = 1; 
if( a = b ) // if( a == b ) 
{ 
	// 执行一些动作 
} 

这样的写法无论在C或C++里都是合法的,但是,你有没有注意到,在if的条件式中,程序设计者有可能少打了一个 = 号,他原先想写下的条件式可能是 a == b,但因为疏失写成了 a = b,而这仍然是可通过编译的C/C++程序代码,它的语义从原先的若a值等于b值则条件成立,变成了将b值指派给变数a,若a在指派后的值大于0,则条件成立。

相信写过C/C++的程序设计者都可能犯下这样子的错误,而且也都能理解这样子的错单纯只是因为输入程序代码的错误,却有可能花上你许多的时间才能找到。从语法上来看,这是从C时代就具备的语法,它很强大、很有弹性,可以写出很取巧的程序代码,但是也留下了让程序设计者犯下上述错误的空间。当然,这样子的语法到了Java,已经不允许了。

你可以在C++中,找到更多更有威力、更有弹性的语法,程序设计者得以凭借来达成很厉害的效果,但是,使用它们要更小心、更谨慎、甚至需要对语言更了解,也更需要技巧,才能将它们运用地淋漓尽致,而且,一不小心,就会犯下难以修正的错误。而其中并不是难在纠正本身,而是难在找到为什么而错。

像C++中的运算子重载,基本上在Java程序语言中是没有的,而像C++中的多重继承,在Java中也仅提供多重接口的实作。从这种角度来看,你可以说Java比较弱,但这是透过刻意削减容易出错的语言元素,来减少程序设计者犯错的机会,即使语言威力变弱了、看起来不那么巧妙了、或许要用比较多的程序代码才能做到一样的事,而程序代码或许看起来很笨,但因为不容易犯错,反而可以提高生产力。

这就是Java尝试提高生产力的一个重要方向。

本文地址:http://www.nowamagic.net/librarys/veda/detail/172,欢迎访问原出处。


推荐阅读
  • 本文详细介绍了暂估入库的会计分录处理方法,包括账务处理的具体步骤和注意事项。 ... [详细]
  • PHP 编程疑难解析与知识点汇总
    本文详细解答了 PHP 编程中的常见问题,并提供了丰富的代码示例和解决方案,帮助开发者更好地理解和应用 PHP 知识。 ... [详细]
  • 优化ListView性能
    本文深入探讨了如何通过多种技术手段优化ListView的性能,包括视图复用、ViewHolder模式、分批加载数据、图片优化及内存管理等。这些方法能够显著提升应用的响应速度和用户体验。 ... [详细]
  • 郑州大学在211高校中的地位与排名解析
    本文将详细解读郑州大学作为一所位于河南省的211和双一流B类高校,在全国211高校中的地位与排名,帮助高三学生更好地了解这所知名学府的实力与发展前景。 ... [详细]
  • 深入理解 Oracle 存储函数:计算员工年收入
    本文介绍如何使用 Oracle 存储函数查询特定员工的年收入。我们将详细解释存储函数的创建过程,并提供完整的代码示例。 ... [详细]
  • 优化ASM字节码操作:简化类转换与移除冗余指令
    本文探讨如何利用ASM框架进行字节码操作,以优化现有类的转换过程,简化复杂的转换逻辑,并移除不必要的加0操作。通过这些技术手段,可以显著提升代码性能和可维护性。 ... [详细]
  • 本文总结了2018年的关键成就,包括职业变动、购车、考取驾照等重要事件,并分享了读书、工作、家庭和朋友方面的感悟。同时,展望2019年,制定了健康、软实力提升和技术学习的具体目标。 ... [详细]
  • 电子元件封装库:三极管、MOS管及部分LDO(含3D模型)
    本资源汇集了常用的插件和贴片三极管、MOS管以及部分LDO的封装,涵盖TO和SOT系列。所有封装均配有高质量的3D模型,共计96种,满足日常设计需求。 ... [详细]
  • 在计算机技术的学习道路上,51CTO学院以其专业性和专注度给我留下了深刻印象。从2012年接触计算机到2014年开始系统学习网络技术和安全领域,51CTO学院始终是我信赖的学习平台。 ... [详细]
  • CSS 布局:液态三栏混合宽度布局
    本文介绍了如何使用 CSS 实现液态的三栏布局,其中各栏具有不同的宽度设置。通过调整容器和内容区域的属性,可以实现灵活且响应式的网页设计。 ... [详细]
  • 本文详细介绍了如何使用PHP检测AJAX请求,通过分析预定义服务器变量来判断请求是否来自XMLHttpRequest。此方法简单实用,适用于各种Web开发场景。 ... [详细]
  • 小红书提高MCN机构入驻门槛,需缴纳20万元保证金
    近期,小红书对MCN机构的入驻要求进行了调整,明确要求MCN机构在入驻时需缴纳20万元人民币的保证金。此举旨在进一步规范平台内容生态,确保社区的真实性和用户体验。 ... [详细]
  • Linux 系统启动故障排除指南:MBR 和 GRUB 问题
    本文详细介绍了 Linux 系统启动过程中常见的 MBR 扇区和 GRUB 引导程序故障及其解决方案,涵盖从备份、模拟故障到恢复的具体步骤。 ... [详细]
  • 动物餐厅高效获取小鱼干攻略
    本文将介绍2023年动物餐厅中快速赚取小鱼干的有效方法,帮助玩家更轻松地积累资源。 ... [详细]
  • This guide provides a comprehensive step-by-step approach to successfully installing the MongoDB PHP driver on XAMPP for macOS, ensuring a smooth and efficient setup process. ... [详细]
author-avatar
手机用户2502884625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有