http://developer.51cto.com/art/200906/126199.htm

差异一:变量作用域的不同

如下面这段程序代码是符合C++语言的语法要求的。其可以在C语言下正常运行。但是其在Java语言平台下编译的时候,就会被告知有错误。其格式、关键字上面都没有错误。那么错误到底是这么呢?这就关系到变量的作用域。

{
float y=3.15 { float y=3.15 } }

作用域就决定了其定义的变量名的可见性与生命周期。在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++语言在作用域上的差异浅析的更多相关文章

  1. Java 和C/C++的“语法”上的差异!

    额其实认为语言语法之间是没有可比性的! 但是因为额曾经学过C/C++,而今又学Java,有赵本山说的话:“知识都学杂了!”,所以我个人总结一下,望提醒自己! Java C++ double 要用%f: ...

  2. Java EE之表达式语言EL(上)

    1.了解表达式语言 表达式语言(EL)用于在不使用脚本.声明或者表达式的情况下,在JSP页面中渲染数据. EL曾是JSTL 1.0规范(与JSP 1.2)中的一部分,并且只可以用作JSTL标签的特性. ...

  3. atitit.java解析sql语言解析器解释器的实现

    atitit.java解析sql语言解析器解释器的实现 1. 解析sql的本质:实现一个4gl dsl编程语言的编译器 1 2. 解析sql的主要的流程,词法分析,而后进行语法分析,语义分析,构建sq ...

  4. Java替代C语言的可能性

        前不久CSDN刊登了一篇<C语言已经死了>的文章,引起了一些争论.事实上那篇文章是从Ed Burnette的博客上转载来的,原文题目是“Die, C, die!”,直译过来应该是& ...

  5. 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. 动态参 ...

  6. 乐字节Java学习01-Java语言概述,Java发展前景,Java的特点

    从这篇文章开始,小乐准备写一整系列的Java学习文章,一步一步带您进入Java的神奇世界! 这是第一篇:Java语言概述以及Java的发展前景 1.SUN公司介绍 SUN公司全称是Stanford U ...

  7. [转载]java中import作用详解

    [转载]java中import作用详解 来源: https://blog.csdn.net/qq_25665807/article/details/74747868 这篇博客讲的真的很清楚,这个作者很 ...

  8. Java基础面试题(史上最全、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  9. 分享:写了一个 java 调用 C语言 开发的动态库的范例

    分享:写了一个 java 调用 C语言 开发的动态库的范例 cfunction.h   代码#pragma once#ifdef __cplusplusextern "C" {#e ...

随机推荐

  1. hihoCoder 1632 Secret Poems(ACM-ICPC北京赛区2017网络同步赛)

    时间限制:1000ms 单点时限:1000ms 内存限制:256MB 描述 The Yongzheng Emperor (13 December 1678 – 8 October 1735), was ...

  2. MT【182】系数奇怪的二次函数

    设函数$f(x)=3ax^2-2(a+b)x+b,$其中$a>0,b\in R$证明:当$0\le x\le 1$时,$|f(x)|\le \max\{f(0),f(1)\}$ 分析:由$a&g ...

  3. 洛谷P3950 部落冲突(LCT)

    洛谷题目传送门 最无脑LCT题解,Dalao们的各种算法都比这个好多啦... 唯一的好处就是只管码代码就好了 开战cut,停战link,询问findroot判连通性 太无脑,应该不用打注释了.常数大就 ...

  4. 【ARC082E】ConvexScore

    Description 给定二维直角坐标系上的N个点\((X_i,Y_i)\),定义一个有N个点中的部分点所构成点集为"凸点集",当且仅当该集合内的所有点恰好构成一个面积为正的凸多 ...

  5. Python基础学习(三)

    了解了Python的基础使用,接下来继续练手廖雪峰老师的教学案例. 一.变量可以指向函数 说明,一个函数可以赋值给一个变量,该变量就会具有该函数的功能,举例: gg = abs print( gg(- ...

  6. ssm框架中Controller层的junit测试_我改

    Controller测试和一般其他层的junit测试可以共用一个BaseTest 一.BaseTest如下: @RunWith(SpringJUnit4ClassRunner.class) @WebA ...

  7. php编程——验证码的实现(session方法)

    index.PHP(实现输入验证码页面)代码如下: <html><head><title>check code</title></head> ...

  8. Hadoop生态圈-Azkaban实现hive脚本执行

    Hadoop生态圈-Azkaban实现hive脚本执行 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客中在HDFS分布式系统取的数据,而这个数据的是有之前我通过MapRed ...

  9. np.random.choice方法

    np.random.choice方法 觉得有用的话,欢迎一起讨论相互学习~Follow Me def choice(a, size=None, replace=True, p=None) 表示从a中随 ...

  10. python---django中orm的使用(2)

    1.基于对象的正向查询和反向查询 在python---django中orm的使用(1)中也提到了正向和反向查找 表:一对多  书籍和出版社 class Book(models.Model): titl ...