声明
本文有牛旦教育原创,首发头条,转载请注明来源,所有权保留。
我们知道类中的成员(包括静态和非静态的字段和方法)作用域对外(不同的包和不同的类)是依赖类的访问控制等级的,对内(同类内)则都可访问。因为类成员变量对类来说是全局变量,即在成员变量定义的代码块(类)内都是有效的。除了全局变量,还有局部变量。本文的4条规则,主要是针对局部变量而言的。
提示:关于类成员访问控制等级——也有称为访问权限的,在JAVA中有4类,每个成员的访问等级只能选择其中的一种。如下下表所示:
表1:类中的成员访问级别
所谓局部变量,就是在方法、构造函数或块中声明的变量。在方法中声明的局部变量仅在方法执行期间存在。由于局部变量仅存在临时的持续时间,因此不能在方法、构造函数或声明块的外部使用。方法的形式参数被视为局部变量。当方法被调用时,以及在执行方法的主体之前,它们都使用实际的参数值进行初始化。编码时,我们需要遵守以下有关使用局部变量的规则。
局部变量默认情况下未初始化。请注意,此规则与实例/类变量初始化的规则相反。当声明一个实例/类变量时,它会使用默认值进行初始化(自动初始化)。来看下面add()方法的以下部分定义:
int add(int n1, int n2) { int sum; /* sum的值是设么? 不知道,因为还没初始化它. */ /* 其它代码... */ }
这条规则是第一条规则的分支。 在程序分配一个值之前,局部变量不能被访问。 下面的代码片段会产生编译时错误,因为它会在分配值之前尝试打印本地变量sum的值。 请注意,Java运行时必须读取(或访问)sum变量的值才能打印它。
int add(int n1, int n2) { int sum; // 编译时错误. 不能读取sum 值,因为还没被赋值. System.out.println(sum); }
下面的代码段编译良好,因为局部变量sum在被读取前已被初始化:
int add(int n1, int n2) { int sum = 0; System.out.println(sum); // 编译运行正常,输出 0 }
局部变量可以在方法体内的任何地方声明。 但是,它必须在使用之前进行声明。 这条规则的含义是,你不需要在方法体的开头声明所有的局部变量。 在更靠近使用变量的地方来声明变量是一个好习惯。
局部变量不允许同名。其实,同一代码块内(不含内嵌代码块)也不允许变量同名,而不论是否是不同类型。
局部变量隐藏实例变量和具有相同名称的类变量的名称。何为隐藏?就是说在类内定义了成员变量name,又定义了局部变量name,再在方法体或代码块使用name变量,则程序会自动选择“最近”定义的变量name。也就是说同名的变量名,会以局部变量为准来参与相关的逻辑处理。如果本想使用成员变量的,这么一来,结果可能不是想要的。
隐藏这一现象适用于所有代码块,即小区块代码内的局部变量,会隐藏大区块同名的变量。
变量作用域示例:
public class VariableScope{ private static int varNumber = 4 ; static void SayNumber(int varNumber){ System.out.println("SayNumber(int varNumber):"+varNumber) ; int varNum = 2 ;//只能方法内使用 System.out.println("Another varNum:"+varNum) ; } public static void main(String[] args){ int varNumber = 9 ; SayNumber(varNumber) ; { int varNum = 3 ; System.out.println("Block Code:"+ varNum) ; } //System.out.println("block variable varNum(3):"+varNum) ;//编译错误 System.out.println("main 内(9):"+varNumber) ; } }
其实,所有的变量作用域都是跟Java的JVM内部管理机制以及内存模型有关的,这里就不展开了,前面有文章说过这些,有兴趣的可以去看看: