John Squirrels
第 41 级
San Francisco

作用域

已在 随机的 群组中发布
我们都知道,国家有边界,也有自己的法律。该国的法律在境内运作。在该国,例如学校或博物馆等组织也有自己的地方规则。它们不与国家法律相抵触,只在特定组织的框架内运作。在编程中也是如此。所以在编程中,特别是在 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));
   }
}
SurnamenamesecondNamebirthday是实例变量。

块作用域

如果在某个代码块中定义/声明了一个变量,那么它会一直存在到该代码块的末尾。通常,此类变量存在于定义它们的花括号之间。块作用域通常可以是一个循环变量。在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是限制最少的修饰符。它允许您不仅可以从声明的类中访问类、方法或变量,还可以从外部访问它们。这个修饰符经常使用。

评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION