《Java 7程序设计入门经典》一2.5 变量的作用域和生命周期

简介: 本节书摘来自华章出版社《Java 7程序设计入门经典》一书中的第2章,第2.5节,作者(美)Herbert Schildt Dale Skrien,更多章节内容可以访问云栖社区“华章计算机”公众号查看

2.5 变量的作用域和生命周期

直至现在,我们使用的所有变量都在main()方法开始处声明。但是,Java允许在块内声明变量。正如第1章介绍的那样,块以左花括号开始,以右花括号结束。块定义一个作用域(scope)。于是,每次开始一个新块时,就创建一个新的作用域。作用域决定哪些对象对程序的其他部分可见。它还决定这些对象的生命周期。
许多其他计算机语言定义两种类型的作用域:全局作用域和局部作用域。尽管这对Java也勉强成立,但是这并不是对Java作用域进行分类的最好办法。Java最重要的作用域是由类和方法定义的作用域。本书在后面介绍类的时候,会讨论类(及其内部定义的变量)的作用域。现在只讨论定义在方法内部的作用域。
由方法定义的作用域以左花括号开始。但是,如果某个方法有形参,它也在方法的作用域内。
一般而言,在作用域内定义的变量对定义域外的代码是不可见的(即不可访问的)。于是,当在一个作用域定义一个变量时,就将变量限制在局部,防止非法访问和修改。作用域的规则事实上提供封装的基础。
作用域可以嵌套。例如,每次创建一个代码块时,就创建一个新的、嵌套的作用域。这时,外部作用域包括内部作用域。这意味着,在外部作用域中声明的对象在内部作用域中的代码仍然可见。但是,反之不然。在内部作用域中声明的对象在其外部不可见。
为了了解嵌套作用域的效果,请考虑以下程序:
image

正如注释所述,变量x在main()方法开始的作用域内,main()方法里所有后续代码可以访问它。在if块中声明变量y。由于块定义作用域,因此只有块内的其他代码才可见到变量y。这也是为什么注释掉块外的代码(行y=100)的原因。如果去掉该行前的注释符号,就会有编译错误。这是因为变量y在作用域外部。if块内部可以使用变量x,这是因为块内的代码(即嵌套作用域)可以访问作用域内声明的变量。
在块内,可以在任何地方声明变量,但只能在声明过后才有效。于是,如果在方法前声明变量,它对方法内的所有代码都有效。反之,若在块的末尾声明一个变量,由于没有代码可以访问它,因此它是毫无用处的。
另外还有一个要点:在进入作用域时创建变量,在作用域结束时销毁变量。这意味着,一旦出了作用域,变量就不再有其曾经的值。于是,在方法内声明的变量在各次调用间不能保存变量的值。同时,在块结束时,块中声明的变量就失去了它的值。于是,变量的作用域限制了其生命周期。
如果变量的声明包括初始化,在每次进入声明该变量的块时都会对变量初始化。例如,下面的程序:
image

程序输出如下所示:
image

可以看到,每次进入for循环时变量y初始化为-1。尽管曾经将值100赋予它,但是这个值丢失了。
Java还有一个令人惊奇的怪癖:尽管块可以嵌套,但是在内部作用域声明的变量不能和外部作用域声明的变量名字相同。例如,下面的程序试图声明两个名字相同的变量,它不能通过编译:
image

从这点看,其他语言(比如,著名的C和C++语言)对内部作用域中声明变量的名字就没有限制。所以,在C或C++中,外层for循环块内的count的声明是完全有效的,这样的声明会使外层变量不可见。Java的设计者认为这种机制很容易导致编程错误,所以不允许这么做。
image

相关文章
|
12天前
|
存储 Java
java基础(7)变量以及变量的分类
Java变量是内存中存储数据的基本单元,包含数据类型、名称和字面值。变量的数据类型决定了分配的内存空间大小。变量声明格式为“数据类型 变量名;”,变量名应符合标识符命名规范。变量可以重新赋值,但数据类型需一致。变量可以一行声明多个,作用域决定了变量的可用范围。变量分为局部变量和成员变量,局部变量定义在方法体内,成员变量定义在方法体外、类体内。
27 2
|
1月前
|
存储 Java 开发者
【Java新纪元启航】JDK 22:解锁未命名变量与模式,让代码更简洁,思维更自由!
【9月更文挑战第7天】JDK 22带来的未命名变量与模式匹配的结合,是Java编程语言发展历程中的一个重要里程碑。它不仅简化了代码,提高了开发效率,更重要的是,它激发了我们对Java编程的新思考,让我们有机会以更加自由、更加创造性的方式解决问题。随着Java生态系统的不断演进,我们有理由相信,未来的Java将更加灵活、更加强大,为开发者们提供更加广阔的舞台。让我们携手并进,共同迎接Java新纪元的到来!
48 11
|
2月前
|
Java
【Java基础面试七】、请介绍一下实例变量的默认值
这篇文章介绍了Java中实例变量的默认值:引用数据类型的默认值是null,而基本数据类型的默认值根据其类型分别是0、0L、0.0F、0.0、'\u0000'和false。
【Java基础面试七】、请介绍一下实例变量的默认值
|
1月前
|
存储 Java 程序员
优化Java多线程应用:是创建Thread对象直接调用start()方法?还是用个变量调用?
这篇文章探讨了Java中两种创建和启动线程的方法,并分析了它们的区别。作者建议直接调用 `Thread` 对象的 `start()` 方法,而非保持强引用,以避免内存泄漏、简化线程生命周期管理,并减少不必要的线程控制。文章详细解释了这种方法在使用 `ThreadLocal` 时的优势,并提供了代码示例。作者洛小豆,文章来源于稀土掘金。
|
2月前
|
存储 安全 Java
Java 中的 ThreadLocal 变量
【8月更文挑战第22天】
36 4
|
2月前
|
安全 Java 编译器
Java 中的 volatile 变量
【8月更文挑战第22天】
23 4
|
24天前
|
JavaScript 前端开发 Java
通过JUnit5访问Java静态、私有、保护变量和方法
在《通过Gtest访问C++静态、私有、保护变量和方法》一文中介绍了如何通过Gtest访问C++静态、私有、保护变量和方法,本文介绍如何通过Junit5访问Java静态、私有、保护变量和方法。
18 0
|
2月前
|
存储 Java 测试技术
Java零基础(15) - Java变量
【8月更文挑战第15天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
27 3
|
2月前
|
存储 Java 测试技术
Java零基础(14) - Java作用域,了解一下!
【8月更文挑战第14天】🏆本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
47 4
|
2月前
|
存储 Java 测试技术
Java零基础教学(14):Java变量详解
【8月更文挑战第14天】Java零基础教学篇,手把手实践教学!
17 2
下一篇
无影云桌面