【转载】Java与C++语言在作用域上的差异浅析
http://developer.51cto.com/art/200906/126199.htm
差异一:变量作用域的不同
如下面这段程序代码是符合C++语言的语法要求的。其可以在C语言下正常运行。但是其在Java语言平台下编译的时候,就会被告知有错误。其格式、关键字上面都没有错误。那么错误到底是这么呢?这就关系到变量的作用域。
{ |
作用域就决定了其定义的变量名的可见性与生命周期。在C++语言(包括其衍生出来的其他语言)与Java语言中,都是用一定花括号来代表一个作用域的。如上面的代码,就表示有两个作用域。外面一对花括号代表一级作用域;里面一对花括号代表二级作用域,依次类推。通常情况下,一级作用域中定义的变量,对其下级作用率都是有效的。也就是说,其下级作用域可以直接引用上级作用域中定义的变量。但是在二级作用域中,可以更改一级作用率中设置的变量值,不过这个更改只在二级作用域内部有效。如上面这个代码,在二级作用域中可以再定义一个y变量,重新赋值。注意,其实在二级作用域中定义的变量与一级作用域中定义的变量,虽然名字相同,但是他们不是同一个变量。如果此时在一级作用域外,有其他代码引用这个y变量的话,则其的值仍然是3.14,而不会是3.15。也就是说,在二级作用域中定义的变量,只在其内部有效。对于上级作用域是没有丝毫影响的。也就是说,在作用域中定义的变量只在其作用域内有效。出了其作用域外,其内部设置的变量就全部无效了。
这个作用域的设置其实Java语言与C++语言是类似的。但是在细节上Java语言又多了一条限制。如上表的代码所示,虽然在上面的代码中变量y在两个不同的作用域中定义,照理来说是两者是互不干涉,可以共存。但是在Java编译器中,是不允许有这种情况存在的。把上面这个代码在Java编译器中编译的话,编译器会通知程序开发人员,说这个变量y已经定义过。然后编译会以错误告终。虽然在C++语言中在不同级别的作用域中定义名字相同的变量是允许的,而在Java语言中则不行,这并不代表在变量的作用域上有所不同。其实从本质上来说,两者变量的作用域是相同的。只是对于Java语言来说,其又多加了一条限制。在Java语言中,即使作用域不同,其定义的变量名字也不能够相同。这主要是为了提高Java代码的可读性,防止混淆才定义了这条规则。
差异二:对象作用域的差异
Java语言与C++语言一样,都是面向对象的语言。不过两者在实现机制上有很大的不同。就拿对象的作用域来说,就有很大的差异。这也导致了两个面向对象的语言在实现细节上的巨大差异。
首先Java程序员需要明白的是,Java对象作用域与变量的作用域是不同的。如上面的分析,变量的作用域只在作用域内部有效。如在二级作用域内定义的变量,超出了二级作用域,那么就无效了。但是对象则不同,其可以存在于作用域之外。如现在在某个作用域内定义了一个name_full对象。当脱离这个作用域的时候,这个对象的引用是消失了。但是刚才创建的这个对象仍然实实在在的保存在内存中。在Java程序的运行过程中,只要通过传递或者复制对象引用的手段,那么在其他作用域内仍然可以访问这个对象。也就是说,只要我们有这个需要,那么在某个作用域内创建的对象其会一直存在并可以在作用域外的其他任何一个地方进行访问。当然前提是要通过复制或者传递等手段把对象引用传递到其他的作用域中。这就是Java对象与Java变量在作用域上最大的不同。
其次,Java对象与C++语言的作用域有很大的不同。其实C++语言中的对象跟变量的作用域到是很类似的。在C++语言中一旦使用完对象之后,就必须把这个对象销毁掉。说的确切一点,就是要在作用域内把使用完的对象所占的内存空间释放掉。否则的话,如果在作用于外部,由于已经失去了对这个对象的引用,为此这个对象就好像成为了太空中的一个人,无法再对其进行任何的操作,只要任其自生自灭。为此对于C++语言来说,程序员很难在脱离作用域外后,确保在需要调用对象时,仍然可以访问这个对象。这也正是C++语言开发过程中最让人头疼的问题。因为需要手工来销毁对象。万一对象所占用的内存空间没有别及时释放的话,那么对于应用程序的安全与性能都会产生很大的影响。
在Java程序中,这个作用域外的对象最终有两个去向。首先,可以通过复制或者传递,在作用域外部仍然可以访问这个对象。其次,就是销毁对象。不过我们不用通过代码来销毁这个以前创建的对象。因为在Java语言中有一种叫做垃圾回收器的处理机制,其可以用来动态监视New关键字创建的所有对象,并根据一定的规则来判断哪些对象不会再被引用。如果其判断某个对象不再被引用话,则会自动释放这些对象所占用的内存空间,以供其他新的对象所使用。我们程序开发人员只管创建对象即可,而不用去担心什么时候去销毁对象。为此,这就可以消除C++语言面临的内存溢出问题。这个内存溢出问题就是因为程序开发人员用完对象后忘记销毁所造成的。
由于在Java程序开发中,我们开发人员不用关心对象的销毁问题,为此可以更多的精力放在代码的优化上。而不像C++语言那样,要把这个对象销毁问题当作头件大事来对待。虽然如此,不过Java程序员也不能够掉以轻心。特别是当我们在离开某个作用域后还需要访问这个对象的时候,一定要记得通过复制或者传递等手段把对象引用传递给其他作用域。否则的话,即使这个对象没有消亡,还实际存储在内存中,但是也会因为缺少了引用而无法访问他们。为此在跨作用域引用对象的时候,这个引用的复制与传递千万不能够忘了。
如果不幸忘了的话,那么在作用域外的代码就无法再访问这个对象。不过这个对象在一定时候会被垃圾回收器回收了。被释放了的内存空间就可以被重复使用,从而防止内存溢出的问题发生。
总之,当Java程序员在开发应用程序的时候,这个Java对象与Java变量作用域的差异,以及Java对象与其他语言对象作用域的差异,一定要了然于胸。这有助于Java程序员能够更好的利用这个Java对象。另外笔者不厌其烦的再强调一遍,默认情况下脱离了某个作用域之后,对象就失去了引用无法访问。如果要在作用域再访问这个对象的时候,则需要及时把这个引用复制或者传递出来。否则的话,作用域外的代码是无法再操作这个对象。
【转载】Java与C++语言在作用域上的差异浅析的更多相关文章
- Java 和C/C++的“语法”上的差异!
额其实认为语言语法之间是没有可比性的! 但是因为额曾经学过C/C++,而今又学Java,有赵本山说的话:“知识都学杂了!”,所以我个人总结一下,望提醒自己! Java C++ double 要用%f: ...
- Java EE之表达式语言EL(上)
1.了解表达式语言 表达式语言(EL)用于在不使用脚本.声明或者表达式的情况下,在JSP页面中渲染数据. EL曾是JSTL 1.0规范(与JSP 1.2)中的一部分,并且只可以用作JSTL标签的特性. ...
- atitit.java解析sql语言解析器解释器的实现
atitit.java解析sql语言解析器解释器的实现 1. 解析sql的本质:实现一个4gl dsl编程语言的编译器 1 2. 解析sql的主要的流程,词法分析,而后进行语法分析,语义分析,构建sq ...
- Java替代C语言的可能性
前不久CSDN刊登了一篇<C语言已经死了>的文章,引起了一些争论.事实上那篇文章是从Ed Burnette的博客上转载来的,原文题目是“Die, C, die!”,直译过来应该是& ...
- atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97
atitit.js javascript 调用c# java php后台语言api html5交互的原理与总结p97 1. 实现html5化界面的要解决的策略1 1.1. Js交互1 1.2. 动态参 ...
- 乐字节Java学习01-Java语言概述,Java发展前景,Java的特点
从这篇文章开始,小乐准备写一整系列的Java学习文章,一步一步带您进入Java的神奇世界! 这是第一篇:Java语言概述以及Java的发展前景 1.SUN公司介绍 SUN公司全称是Stanford U ...
- [转载]java中import作用详解
[转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...
- Java基础面试题(史上最全、持续更新、吐血推荐)
文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...
- 分享:写了一个 java 调用 C语言 开发的动态库的范例
分享:写了一个 java 调用 C语言 开发的动态库的范例 cfunction.h 代码#pragma once#ifdef __cplusplusextern "C" {#e ...
随机推荐
- 初识Java Enum
enum 的全称为 enumeration, 是 JDK 1.5 中引入的新特性,存放在 java.lang 包中. enum是关键字,感觉它跟class.interface是并列的,并且不能跟fi ...
- BZOJ1185 [HNOI2007]最小矩形覆盖 【旋转卡壳】
题目链接 BZOJ1185 题解 最小矩形一定有一条边在凸包上,枚举这条边,然后旋转卡壳维护另外三个端点即可 计算几何细节极多 维护另外三个端点尽量不在这条边上,意味着左端点尽量靠后,右端点尽量靠前, ...
- Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流)
Luogu 2762 太空飞行计划 / Libre 6001 「网络流 24 题」太空飞行计划 (网络流,最大流) Description W 教授正在为国家航天中心计划一系列的太空飞行.每次太空飞行 ...
- debian及ubuntu挂载本地硬盘的ISO镜像文件
1.定位Debian ISO镜像的位置,比如说sda3 fdisk -l 2.挂载: # mount -t auto /dev/sda3 /media/mnt 生成isodebian路径 /mnt# ...
- Qt ------ UDP发送不了或接收不到问题
1.禁用不需要的网卡,比如禁用虚拟机网卡. 2.向所有网卡广播数据 /* * 直接调用 QUdpSocket 的 writeDatagram() 函数发送数据,如果有多张网卡(装了虚拟机会增加网卡), ...
- package.json浅谈
相信很多小伙伴都见过各种各样的Node.js项目,而里面都有一个名为package.json的文件,而这个文件究竟是干什么的呢? 简单的来说,这个文件就是对整个项目的各种情况的配置(也是介绍),下面给 ...
- MySQL初始化以及客户端工具的使用
MySQL初始化以及客户端工具的使用 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是关系型数据库 关系型数据库通常是把所有的数据都组织成二维关系.之所以称为关系型数据库是 ...
- bzoj千题计划180:bzoj4411: [Usaco2016 Feb]Load balancing
http://www.lydsy.com/JudgeOnline/problem.php?id=4411 用树状数组维护扫描线 一个树状数组维护扫描线之上的y<=i点,另一个维护扫描线之下y&l ...
- [软件]在浏览器里添加MarkDown Here(插件)
1. 先来说说这个插件的作用是什么: 用于在网页一些编辑文本的地方, 使用MacDown编辑文本 支持大部分浏览器, https://github.com/adam-p/markdown-here ...
- MongoDB探索之路(三)——索引
1.索引介绍 2.创建语句 1)基础索引 在字段age 上创建索引,1(升序);-1(降序):db.users.ensureIndex({age:1}) _id 是创建表的时候自动创建的索引,此索引是 ...