《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

相关文章
|
6天前
|
存储 传感器 缓存
java变量与数据类型:整型、浮点型与字符类型
### Java数据类型全景表简介 本文详细介绍了Java的基本数据类型和引用数据类型,涵盖每种类型的存储空间、默认值、取值范围及使用场景。特别强调了`byte`、`int`、`long`、`float`、`double`等基本类型在不同应用场景中的选择与优化,如文件流处理、金融计算等。引用数据类型部分则解析了`String`、数组、类对象、接口和枚举的内存分配机制。
35 14
|
2月前
|
Java Linux iOS开发
如何配置 Java 环境变量:设置 JAVA_HOME 和 PATH
本文详细介绍如何在Windows和Linux/macOS系统上配置Java环境变量。
1667 12
|
4月前
|
存储 缓存 安全
除了变量,final还能修饰哪些Java元素
在Java中,final关键字不仅可以修饰变量,还可以用于修饰类、方法和参数。修饰类时,该类不能被继承;修饰方法时,方法不能被重写;修饰参数时,参数在方法体内不能被修改。
51 3
|
4月前
|
Java 程序员 容器
Java中的变量和常量:数据的‘小盒子’和‘铁盒子’有啥不一样?
在Java中,变量是一个可以随时改变的数据容器,类似于一个可以反复打开的小盒子。定义变量时需指定数据类型和名称。例如:`int age = 25;` 表示定义一个整数类型的变量 `age`,初始值为25。 常量则是不可改变的数据容器,类似于一个锁死的铁盒子,定义时使用 `final` 关键字。例如:`final int MAX_SPEED = 120;` 表示定义一个名为 `MAX_SPEED` 的常量,值为120,且不能修改。 变量和常量的主要区别在于变量的数据可以随时修改,而常量的数据一旦确定就不能改变。常量主要用于防止意外修改、提高代码可读性和便于维护。
|
4月前
|
Java 编译器
Java重复定义变量详解
这段对话讨论了Java中变量作用域和重复定义的问题。学生提问为何不能重复定义变量导致编译错误,老师通过多个示例解释了编译器如何区分不同作用域内的变量,包括局部变量、成员变量和静态变量,并说明了使用`this`关键字和类名来区分变量的方法。最终,学生理解了编译器在逻辑层面检查变量定义的问题。
Java重复定义变量详解
|
4月前
|
Java API 调度
Java 线程的生命周期
在JDK 1.5之前,线程的生命周期包括五种状态:新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)。JDK 1.5及之后增加了三种阻塞状态,共六种状态:新建、可运行、终止、锁阻塞、计时等待和无限等待。这些状态描述了线程在操作系统和JVM中的不同阶段。
131 4
Java 线程的生命周期
|
5月前
|
Java 调度
[Java]线程生命周期与线程通信
本文详细探讨了线程生命周期与线程通信。文章首先分析了线程的五个基本状态及其转换过程,结合JDK1.8版本的特点进行了深入讲解。接着,通过多个实例介绍了线程通信的几种实现方式,包括使用`volatile`关键字、`Object`类的`wait()`和`notify()`方法、`CountDownLatch`、`ReentrantLock`结合`Condition`以及`LockSupport`等工具。全文旨在帮助读者理解线程管理的核心概念和技术细节。
60 1
[Java]线程生命周期与线程通信
|
5月前
|
Java
通过Java代码解释成员变量(实例变量)和局部变量的区别
本文通过一个Java示例,详细解释了成员变量(实例变量)和局部变量的区别。成员变量属于类的一部分,每个对象有独立的副本;局部变量则在方法或代码块内部声明,作用范围仅限于此。示例代码展示了如何在类中声明和使用这两种变量。
|
5月前
|
Java 测试技术 开发者
💡Java 零基础:彻底掌握 for 循环,打造高效程序设计
【10月更文挑战第15天】本文收录于「滚雪球学Java」专栏,专业攻坚指数级提升,希望能够助你一臂之力,帮你早日登顶实现财富自由🚀;同时,欢迎大家关注&&收藏&&订阅!持续更新中,up!up!up!!
156 63
|
5月前
|
Java 编译器
java“变量 x 可能未被初始化”解决
在Java中,如果编译器检测到变量可能在使用前未被初始化,会报“变量 x 可能未被初始化”的错误。解决方法包括:1. 在声明变量时直接初始化;2. 确保所有可能的执行路径都能对变量进行初始化。
411 2

热门文章

最新文章