【转载】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 ...
随机推荐
- Allowed Letters CodeForces - 1009G(状压思维)
题意: 给出一个字符串 给出几个定点必须是哪个字母(或者是几个字母中的一个) 然后求在满足所有定点后的最小字符串 解析: 没错 这题是暴力 用状压暴力 “a - f” 用”0 - 5“ 这几个数字代 ...
- 洛谷P3935 Calculating(整除分块)
题目链接:洛谷 题目大意:定义 $f(x)=\prod^n_{i=1}(k_i+1)$,其中 $x$ 分解质因数结果为 $x=\prod^n_{i=1}{p_i}^{k_i}$.求 $\sum^r_{ ...
- 让外部网络访问K8S service的四种方式
本文基于kubernetes 1.5.2版本编写 kube-proxy+ClusterIP kubernetes版本大于或者等于1.2时,配置: 修改master的/etc/kubernetes/pr ...
- 构造方法和一般方法的区别(面试)-----java基础知识总结
构造方法:对象创建时,就会调用与之对应的构造方法,对对象进行初始化: 一般方法:对象创建后,需要方法功能时才会调用. 构造方法,在对象创建时,会调用且只调用一次. 一般方法,对象创建后,可以被调用多次 ...
- Helm一:简介
目录 什么是Helm Helm解决的问题 Helm原理 Helm架构 Helm功能 Helm三个重要概念 Helm组件 Helm Client Tiller Server Helm实现 什么是Helm ...
- Sql Server数据库小知识点总结
把我在开发时候遇到的一点小知识持续更新在这里~ 1.where条件时常变 where UserID='1' 这里的UserID呢,它的值是经常在变化的,有时候要查2,有时候要查3的,有时候要查全部人! ...
- webstorm去掉vue错误提示
- .NET面试题系列(六)多线程
1.多线程的三个特性:原子性.可见性.有序性 原子性:是指一个操作是不可中断的.即使是多个线程一起执行的时候,一个操作一旦开始,就不会被其他线程干扰. 比如,对于一个静态全局变量int i,两个线程同 ...
- CF734F Anton and School (构造)
\(solution\) : 这道题做法很巧妙,需要对位运算有足够了解: $( a $ & $ b )$ \(+\) $( a $ | $ b )$ \(=\) \(a+b\) ,所以有 \( ...
- Django安装配置
django2.0基础 一.安装与项目的创建 1.安装 pip install django 2.查看版本 python -m django --version 3.创建项目 django-admin ...