热门标签 | 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,欢迎访问原出处。


推荐阅读
  • 精选煲机软件推荐:提升耳机音质的秘密武器
    本文介绍了几款市面上流行的煲机软件,包括它们的特点、使用方法以及如何通过这些工具有效提升耳机和音箱的音质。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • 在1995年,Simon Plouffe 发现了一种特殊的求和方法来表示某些常数。两年后,Bailey 和 Borwein 在他们的论文中发表了这一发现,这种方法被命名为 Bailey-Borwein-Plouffe (BBP) 公式。该问题要求计算圆周率 π 的第 n 个十六进制数字。 ... [详细]
  • 本文详细介绍了如何在Oracle VM VirtualBox中实现主机与虚拟机之间的数据交换,包括安装Guest Additions增强功能,以及如何利用这些功能进行文件传输、屏幕调整等操作。 ... [详细]
  • CSS Border 属性:solid 边框的使用详解
    本文详细介绍了如何在CSS中使用solid边框属性,包括其基本语法、应用场景及高级技巧,适合初学者和进阶用户参考。 ... [详细]
  • 2023年,Android开发前景如何?25岁还能转行吗?
    近期,关于Android开发行业的讨论在多个平台上热度不减,许多人担忧其未来发展。本文将探讨当前Android开发市场的现状、薪资水平及职业选择建议。 ... [详细]
  • 本文介绍了SIP(Session Initiation Protocol,会话发起协议)的基本概念、功能、消息格式及其实现机制。SIP是一种在IP网络上用于建立、管理和终止多媒体通信会话的应用层协议。 ... [详细]
  • 二维码的实现与应用
    本文介绍了二维码的基本概念、分类及其优缺点,并详细描述了如何使用Java编程语言结合第三方库(如ZXing和qrcode.jar)来实现二维码的生成与解析。 ... [详细]
  • 在日常生活中,支付宝已成为不可或缺的支付工具之一。本文将详细介绍如何通过支付宝实现免费提现,帮助用户更好地管理个人财务,避免不必要的手续费支出。 ... [详细]
  • 解决Win10系统显示模糊问题的方法
    Windows 10作为一款深受用户喜爱的操作系统,提供了丰富的个性化设置选项,让每位用户都能根据个人偏好定制系统界面。然而,在进行个性化设置的过程中,有时会出现显示模糊的情况,影响用户体验。本文将详细介绍如何有效解决Win10系统显示模糊的问题。 ... [详细]
  • 拨打电话时遇到‘正在通话’或无人接听的情况解析及解决方法
    当您尝试联系他人时,可能会遇到电话提示‘正在通话’或是虽然接通但无人应答的情况。本文将详细解释可能的原因,并提供相应的解决策略。 ... [详细]
  • 本文详细介绍了在Windows系统中如何配置Nginx以实现高效的缓存加速功能,包括关键的配置文件设置和示例代码。 ... [详细]
  • 如何在PyCharm中配置Python脚本的默认模板
    本文介绍如何在PyCharm中设置Python脚本的默认模板,以便每次创建新的.py文件时自动填充预设内容,提高开发效率。 ... [详细]
  • 当需要确保对象的状态在创建后不可更改时,使用记录(Record)类型是一个理想的选择。本文探讨了如何通过记录类型实现对象的不可变性,并提供了一个简单的示例来说明其用法。 ... [详细]
  • 本文详细介绍了FLV播放器的构建过程,包括如何解析FLV标签并将这些标签传递给解码器,以及如何在Qt环境中注册共享指针的信号和槽机制。 ... [详细]
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社区 版权所有