将局部变量的作用域最小化
较早的程序设计语言(如C语言)要求局部变量必须在一个代码块的开头处进行声明,出于习惯,有些程序员继承了这种“优良作风”,这个习惯应该改正。再次提醒,Java允许你在任何可以出现语句的地方声明变量。
要是局部变量的作用域最小化,最有力的方法就是在第一次使用它的地方声明。如果变量在使用之前声明,这只会造成混乱-----对于试图理解程序功能的读者来说,这又多了一种自会分散他们注意力的因素。等到用到该变量的时候,读者已经可能记不起该变量的类型或者初始值了。
过早的声明局部变量不仅会使它的作用域过早的扩展,而且结束得也过于晚了。局部变量的作用域从它被声明的点开始扩展,一直到外围快的结束处。如果变量是在“使用它的块”之外声明的,当程序退出该块之后,该变量仍是可见的。如果变量在它的目标使用区域之前或者之后被意外地使用的话,后果是灾难性的。
几乎每个局部变量的声明都应该包含一个初始化表达式。如果你还没有足够的信息对一个变量进行有意义的初始化,就应该推迟这个声明,直到可以初始化为止。这条规则有个例外的情况与try-catch有关。如果一个变量被一个方法初始化,而这个方法可能会抛出一个受检查的异常(checked exception),该变量就必须在try块的内部被初始化。如果变量的值必须在try块的外部被使用到,就必须在try块之前被声明,但在try块之前,它不能被“有意义的初始化”。
举个简单的例子
public Connection getConnection(){
Connection conn=null;
try {
conn=DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","123456");
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}
循环中提供了特殊的机会将变量的作用域最小化。无论是传统的还是for-each形式的,for循环都允许声明循环变量,它的作用域被限定在正好需要的范围之内。这个范围包括循环体、以及循环之前的初始化、测试、更新部分。因此,如果在循环终止之后不再需要循环变量的内容,for循环就优先于while循环。
例如,下面是一种遍历集合的首选做法
for(Element e:c){
doSomething(e);
}
在java1.5发行版之前,首选的做法如下
for(Iterable i=c.iterable();i.hasNext()){
doSomething(e.next());
}
为了弄清楚为什么这个for循环比while循环更好,请考虑以下代码片段,它包含两个while循环,以及一个BUG;
Iterator<Element> i=c.iterator();
while(i.hasNext()){
doSomething(i.next());
}
...
Iterator<Element> i2=c2.iterator();
while(i.hasNext()){//BUG
doSomething(i2.next());
}
第二个循环中包含一个“剪贴---粘贴”错误:它本来要初始化一个新的变量i2,却使用了旧的循环变量i,遗憾的是,这时i仍然在有效范围内。结果代码仍然可以编译,运行的时候不会抛出异常,但是它所做的事情确实错误的。因为这个错误是悄然发生的,所以可能在很长时间内不会出现被发现。
如果类似的“剪贴---粘贴”错误发生在前面任何一种for循环汇中,结果代码就不能通过编译。在第二个循环开始之前,第一个循环的元素变量已经不在它的作用域范围之内了。
for(Iterable<Element> i=c.iterable();i.hasNext()){
doSomething(i.next());
}
...
//编译错误 提示找不到变量i
for(Iterable<Element> i2=c2.iterable();i.hasNext()){
doSomething(i2.next());
}
而且,如果使用for循环,犯这种“剪贴---粘贴”错误的可能性就会大大的降低,因为通常没有必要在两个循环中声明不同的变量名。循环是完全独立的,所以重用元素变量的名称不会有任何的危害。实际上,这也是很流行的做法。
使用for循环与使用while循环相比还有另外一个优势:更简短,从而增加了可读性。
下面是另外一种对局部变量的作用域进行最小化的循环做法。
for(int i=0;i=sss();i<n;i++){
doSomething(i);
}
关于这种做法要关注的一点是,它有两个循环变量:i和n,两者具有完全相同的作用域。第二个变量n被用来保存第一个变量的极限值,从而避免在每次迭代中执行冗余计算的开销。通常,如果循环中涉及方法调用,它可以保证在每次迭代中都会返回同样的结果。
最后一种“将局部变量的作用域最小化”的方法是使方法小而集中。如果把两个操作合并到同一个方法中,与其中一个操作相关的局部变量就有可能会出现在执行另一个操作的代码范围之内。为了防止这种情况发生,只要把这个方法分成两个,每个方法各执行一个操作。
分享到:
相关推荐
"Effective Java读书笔记" Effective Java是一本关于Java编程语言的经典书籍,本笔记主要总结了Java语言的发展历程、静态工厂方法的应用、构造器模式的使用等重要知识点。 一、Java语言的发展历程 Java语言的发展...
《Effective Java》是Java开发领域的经典著作,作者Joshua Bloch深入浅出地阐述了编写高效、健壮的Java代码的技巧和最佳实践。以下是对该书部分内容的详细解释: 1. **产生和销毁对象** - Item1:静态工厂方法相比...
根据给定的文件信息,以下是对“精版Effective STL读书笔记”的详细解析,重点提炼了STL(标准模板库)中的关键知识点。 ### 标题:“精版Effective STL读书笔记” 此标题暗示了文档是针对《Effective STL》一书的...
Effective Java 读书笔记 - 枚举与注解 本文总结了Effective Java 中关于枚举与注解的知识点,涵盖了枚举类型的优点、使用指南、避免使用 int 常量、使用 EnumSet 和 EnumMap 等。 枚举类型的优点 枚举类型提供了...
《Effective Java》是Java...以上仅是《Effective Java》一书中部分核心知识点的概述,实际的读书笔记中会更详细地解释这些概念,并给出具体的示例代码。通过深入学习和实践,开发者可以极大地提升其Java编程的水平。
《Effective Java》是Java编程领域的一本经典著作,由Joshua Bloch撰写,该书的第三版继续提供了关于如何编写高效、优雅、可维护的Java代码的指导。以下是基于给出的目录和部分内容提取的一些关键知识点: ### 第一...
从给出的部分内容来看,读书笔记主要聚焦于以下几个知识点: 1. C++语言的联邦概念:C++是一个由多个次语言构成的语言联邦,这包括了C语言核心、面向对象的C++、模板C++以及标准模板库(STL)。这种理解对于深入...
这本书的第三版包含了大量更新,涵盖了Java语言和平台的新发展,如Java 8和Java 9的新特性。以下是对《Effective Java》笔记中可能涉及的关键知识点的详细解读: 1. **单例模式**:书中强调了如何正确实现单例模式...
"Effective Java 读书分享" 《Effective Java》读书分享.pptx 是一本 Java 编程语言指南,旨在帮助开发者编写高质量、可维护的 Java 代码。该书包含 90 个条目,每个条目讨论一条规则,涵盖了 Java 编程语言的...
读书笔记:Effective Java中文版第3版笔记
### Effective Java读书笔记(上) #### 第一章 引言 本书主要针对Java开发者提供了大量实用的编程指导建议,帮助读者提升代码质量和程序性能。在本章节中,我们将重点介绍对象的创建与销毁,以及一些重要的设计...
effective C++ 很好 很不错 最好的C++进阶资料
读书笔记:Effective Java中文版学习项目
Effective C++读书笔记 本文总结了Effective C++读书笔记,涵盖了C++的四个主要次语言:C、Object-Oriented C++、Template C++和STL。同时,文章还讨论了高效编程守则,包括使用const、enum和inline替换#define,...
读书笔记:Effective Java中文版第二版示例、笔记
读书笔记:Effective Java中文版 第2版
记录了我的effective-Python学习笔记,精简了effective-Python中重要的部分。effective-Python是一本值得多看几遍的书,但是看后面的几遍的时候完全可以直接看自己的学习笔记。此学习笔记侧重与比较实用的部分即前四...
读书笔记:Java练习包括《Java编程思想》《算法》《Effective Java》等
读书笔记:Effective Java中文版第二版示例代码