我们都知道,国家有边界,也有自己的法律。该国的法律在境内运作。在该国,例如学校或博物馆等组织也有自己的地方规则。它们不与国家法律相抵触,只在特定组织的框架内运作。在编程中也是如此。所以在编程中,特别是在 Java 语言中,有一个术语“作用域”。它指的是某些数据(例如变量或方法)起作用的程序区域。在本文中,我们将弄清楚 Java 中变量的作用域是什么以及如何定义它们。
一般的 Java 作用域
为什么有必要分离变量和方法的范围?事实上,有时程序非常大,很难跟踪一个或另一个变量。此外,在大型项目中,变量的明确命名是可取的,以便清楚它们的用途。作用域特别允许您在程序的不同部分拥有同名的不同变量。这样的代码更容易维护和阅读。Java 范围定义了程序中某个变量或方法的可访问位置。简要地:- 在方法中声明的变量从声明开始到方法结束(方法范围)都是可见的。
- 在代码块中声明的变量一直存在到该代码块的末尾。
- 作为方法参数的变量一直存在到方法结束。
- 类/对象变量在包含对象的生命周期内存在。它们的可见性由特殊的访问修饰符控制。
- 静态类变量在程序运行时一直存在。它们的可见性也由访问修饰符决定。
方法级范围
方法中声明的任何变量(包括参数)都无法在该方法之外访问。在方法内部声明的所有变量从声明开始到方法结束都是可见的。这是方法变量范围的示例:
public class JScopeTest1 {
public static void main(String[] args) {
System.out.println(myMethod(5));
System.out.println(myMethod(17));
}
public static int myMethod(int arg) {
int secondArg = 100; //local method variable
return secondArg + arg;
}
}
这里我们有secondArg,一个局部变量或方法参数。我们不能在myMethod方法之外或声明它之前使用此变量。如果一个变量是一个函数参数,那么它在这个方法的整个主体中都是可见的。在上面的示例中,我们有两个这样的参数:myMethod 中的 arg 和 main 方法中的 args。
类级别范围
类级范围(实例变量)——类中声明的任何变量都可用于该类的所有方法。根据其访问修饰符(即 public 或 private),它有时可以在类之外访问。所以如果一个变量是类变量,那么它就绑定到一个特定的对象上,只要有这个类的对象就存在。如果没有对象,则没有变量的副本。该变量对于类的所有方法都是可见的,无论它们是在它之前还是之后声明的。每个对象都有自己的独立于其他对象的变量。无法从静态方法访问变量。代码示例
public class Student {
//class level variables
public String surname;
String name;
String secondName;
private Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases
public Student(String surname, String name, String secondName, Date birthday ){
this.surname = surname;
this.name = name;
this.secondName = secondName;
this.birthday = birthday == null ? 0 : birthday.getTime();
}
@Override
public int hashCode(){
//TODO: check for nulls
//return surname.hashCode() ^ name.hashCode() ^ secondName.hashCode() ^ (birthday.hashCode());
return (surname + name + secondName + birthday).hashCode();
}
@Override
public boolean equals(Object other_) {
Student other = (Student)other_;
return (surname == null || surname.equals(other.surname) )
&& (name == null || name.equals(other.name))
&& (secondName == null || secondName.equals(other.secondName))
&& (birthday == null || birthday.equals(other.birthday));
}
}
Surname、name、secondName和birthday是实例变量。
块作用域
如果在某个代码块中定义/声明了一个变量,那么它会一直存在到该代码块的末尾。通常,此类变量存在于定义它们的花括号之间。块作用域通常可以是一个循环变量。在for循环条件中声明的变量在循环外不可访问,除非您事先定义了它。
public class JScopeTest2 {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
int sum = 0;
sum = sum + i;
}
int sum = 1;
System.out.println(sum);
}
}
first sum 和 i 变量都在循环内声明,并且不存在于此循环外。然而,第二个总和是在循环外声明的,所以这个特定的变量将被打印出来。
静态变量
如果一个变量被声明为静态的(用 static 关键字标记),那么只要它的类存在,它就存在。通常,当初始化静态变量时,JVM 会在首次使用时将类加载到内存中。
import java.util.Date;
public class Student {
public static int today = 2022;
String surname;
String name;
String secondName;
Long birthday; // Long instead of long is used by Gson/Jackson json parsers and various orm databases
public Student(String surname, String name, String secondName, Date birthday ){
this.surname = surname;
this.name = name;
this.secondName = secondName;
this.birthday = birthday == null ? 0 : birthday.getTime();
}
public static void main(String[] args) {
System.out.println(today);
}
}
您不应该创建Student类 的新实例来使用静态today变量。这里将打印“2022”。
访问修饰符
Java 有 4 个访问修饰符来限制对方法或变量的访问。您可以在类内部使用它们,而不是在方法内部。-
private是限制性最强的修饰符。它将对方法和变量的访问限制在声明它们的类中。如果不需要在类外使用某些方法或变量,就用private。类变量在 Java 中通常是私有的。
-
如果没有指定访问修饰符,方法或变量将接受默认修饰符。默认只允许从当前包访问。
-
protected修饰符只允许从当前包内访问方法或变量,除非通过包外的子类访问。
-
public是限制最少的修饰符。它允许您不仅可以从声明的类中访问类、方法或变量,还可以从外部访问它们。这个修饰符经常使用。
GO TO FULL VERSION