Java变量和对象的作用域

 更新时间:2017年03月28日 10:55:27   作者:AlanLee(Java)  
本文主要介绍了Java变量和对象的作用域的相关知识。具有很好的参考价值,下面跟着小编一起来看下吧

大多数程序设计语言都提供了“作用域”(Scope)的概念。

对于在作用域里定义的名字,作用域同时决定了它的“可见性”以及“存在时间”。在C,C++和Java里,作用域是由花括号的位置决定的。

变量的作用域

例子:

{
  int x = 12;
  /* only x available */
  {
    int q = 96;
    /* both x & q available */
  }
  /* only x available */
  /* q “out of scope” */
}

Java用一对大括号作为语句块的范围,称为作用域,作为在作用域里定义的一个变量,它只有在哪个作用域结束之前才可使用。

在Java中不能像下面这样书写代码:

 {
   int x = 12;
   {
     int x = 96; /* illegal */
   }
 }

Java编译器会认为变量已被定义,所以作用域中的变量不能重复定义,但是在C和C++中能将一个变量“隐藏”在一个更大的作用域里,在C和C++中被允许,在Java中是不允许的,因为Java的设计者认为这样做使程序产生了混淆。

再来看两个例子,为了让大家看到效果这里使用截图的方式:

我们再来看这段代码,大家思考一个问题,第11行和第12行为什么没有语法错误?代码如下:

如果我们交换一下位置呢,代码如下:

离开作用域,变量所分配的内存空间将被JVM回收,所以语法不会有错误,而第二种写法name并没有离开{}作用域,所以会语法错误。

上述的变量都是局部变量,那么如果是在有全局变量的情况下又是怎样一种结果呢?我们来用代码说话,代码如下:

大家仔细的观察并结合代码思考,可以得出变量的作用域结论如下:

在同一作用域范围的包裹下全局变量名和局部变量名是可以变量名相同的,在同一个作用域范围的包裹下局部变量和局部变量不可以变量名相同(作用域内不能重复命名),使用变量的时候如果不指明使用全局变量还是局部变量,那么默认的就是使用局部的那个变量,但是如果局部变量超出了它本身的作用域范围则会失效,被JVM垃圾回收,那么则可以重复命名此变量,并使用最新定义的这个局部变量。

对象的作用域

Java对象不具备与朱类型一样的存在时间。用new关键字创建一个Java对象的时候,它会超出作用域的范围之外。所以假若使用下面这段代码:

 {
   String s = new String("a string");
 } /* 作用域的终点 */

那么句柄s,也就是引用会在作用域的终点处消失。然而,s指向的String对象依然占据着内存空间。在上面这段代码里,我们没有办法继续使用这个对象,因为指向它的唯一一个句柄已经超出了作用域的边界。

这样造成的结果是:对于用new创建的对象,只要我们愿意,它们就会一直保留下去。这个编程问题在C和C++里特别突出。在C++里遇到的麻烦最大:由于不能从语言获得任何帮助,所以在需要对象的时候,根本无法确定它们是否可用。而且最麻烦的是,在C++里,一旦完成工作,必须保证将对象手动清除。

这样便带来了一个有趣的问题。假如 Java 让对象依然故我,怎样才能防止它们大量充斥内存,并最终造成程序的“凝固”呢。在 C++里,这个问题最令程序员头痛。但 Java 以后,情况却发生了改观。 Java 有一个特别的“垃圾收集器”,它会查找用 new 创建的所有对象,并辨别其中哪些不再被引用。随后,它会自动释放由那些闲置对象占据的内存,以便能由新对象使用。这意味着我们根本不必操心内存的回收问题。只需简单地创建对象,一旦不再需要它们,它们就会自动离去。这样做可防止在 C++里很常见的一个编程问题:由于程序员忘记释放内存造成的“内存溢出”。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持脚本之家!

相关文章

  • IDEA中设置Run Dashboard方式

    IDEA中设置Run Dashboard方式

    这篇文章主要介绍了IDEA中设置Run Dashboard方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • SpringBoot+JWT实现单点登录完美解决方案

    SpringBoot+JWT实现单点登录完美解决方案

    单点登录是一种统一认证和授权机制,指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的系统,不需要重新登录验证,这篇文章主要介绍了SpringBoot+JWT实现单点登录解决方案,需要的朋友可以参考下
    2023-07-07
  • spring-boot报错java: 程序包javax.servlet.http不存在

    spring-boot报错java: 程序包javax.servlet.http不存在

    当springboot项目从2.7.x的升级到3.0.x的时候,会遇到一个问题java: 程序包javax.servlet.http不存在,下面就来具体介绍一下,感兴趣的可以了解一下
    2024-08-08
  • 第三方包jintellitype实现Java设置全局热键

    第三方包jintellitype实现Java设置全局热键

    本文主要介绍了,在java中使用第三方插件包jintellitype来实现全局热键,非常的简单,但是很实用,有需要的朋友可以参考下,欢迎一起来参与改进此项目
    2014-09-09
  • Springboot hibernate envers使用过程详解

    Springboot hibernate envers使用过程详解

    这篇文章主要介绍了Springboot hibernate envers使用过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-06-06
  • Java基础之文件和目录操作

    Java基础之文件和目录操作

    这篇文章主要介绍了Java基础之文件和目录操作,文中有非常详细的代码示例,对正在学习java基础的小伙伴们有很好地帮助,需要的朋友可以参考下
    2021-05-05
  • springboot项目启动的时候,运行main方法报错NoClassDefFoundError问题

    springboot项目启动的时候,运行main方法报错NoClassDefFoundError问题

    这篇文章主要介绍了springboot项目启动的时候,运行main方法报错NoClassDefFoundError问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-01-01
  • Java 定时器的多种实现方式

    Java 定时器的多种实现方式

    本文介绍了Java中定时器的多种实现方式,有此需求的朋友可以根据实际选择适合自己的方式
    2021-06-06
  • Spring Cloud Gateway远程命令执行漏洞分析(CVE-2022-22947)

    Spring Cloud Gateway远程命令执行漏洞分析(CVE-2022-22947)

    使用Spring Cloud Gateway的应用程序在Actuator端点启用、公开和不安全的情况下容易受到代码注入的攻击,攻击者可以恶意创建允许在远程主机上执行任意远程执行的请求,这篇文章主要介绍了Spring Cloud Gateway远程命令执行漏洞(CVE-2022-22947),需要的朋友可以参考下
    2023-03-03
  • 反射机制:getDeclaredField和getField的区别说明

    反射机制:getDeclaredField和getField的区别说明

    这篇文章主要介绍了反射机制:getDeclaredField和getField的区别说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06

最新评论