“教授很容易墨守成规。习惯于讲课的老教师总是如此。他只能给你讲授书本上的东西。你不会通过听游泳课来学习如何游泳。只有当你熟悉主题并且知道的几乎跟教授一样多时,讲座才有用。”

“不过,他的课还是有用的。”

“是的。我是说,但愿如此。你所听到的有关主题的观点越多,你就越接近真相。如果只听到一种观点,你所能做的只是相信它或不相信它。好吧,让我们言归正传。”

“现在来一张我以前给你看过的照片。”


public class Variables


   private static String TEXT = "结束。";
  ┗━━━━━━━━━━━━━━━━━━━┛
   public static void main (String[] args)
                          ┗━━━━━━━┛
  {
     System.out.println("你好");
     String s = "你好!";
   ┏┗━━━━┛
    System.out.println(s);
    if (args != NULL)
    {
       String s2 = s;
      ┗━━━━┛
   
      System.out.println(s2);
     
    }
    Variables variables = new Variables();
    System.out.println(variables.instanceVariable);
    System.out.println(TEXT);
   
  }
 
   public String instanceVariable;
  ┗━━━━━━━━━━━━━━━┛
   public Variables()
   {
      instanceVariable = "实例变量测试。";
   }
}

1.在方法中声明的变量从其声明开始到方法结束一直存在(可见)。

2.在代码块中声明的变量在代码块结束之前一直存在。

3.方法的参数在方法返回前一直存在。

4.对象中的变量在包含它们的对象的整个生命周期中都存在。它们的可见性也可以由特殊访问修饰符控制。

5.static(类)变量在程序运行的整个过程中都存在。它们的可见性也可以由访问修饰符定义。”

"是的。我记得这张照片。”

“好的。我来提醒你一些要点。”

“在方法内声明的所有变量从声明开始到方法结束一直存在(可见)(示例1)。”

“如果变量是在代码块中声明的,则它在代码块结束之前一直存在(示例 2)。”

“如果变量是方法参数,则它在方法的整个主体中都存在(可见)(示例3)。”

“如果变量是实例变量(示例4),则它链接到某个对象,并且在对象存在期间一直存在。如果没有对象,则该变量没有任何实例。可以从类的所有方法中访问变量(即变量可见),无论这些方法是在该变量之前还是之后声明的。将为每个对象创建一个新变量。该变量独立于其他对象。不能从 static 方法访问实例变量。

“如果变量被声明为 static,即标记有关键字 static,则它在类存在期间一直存在。JVM 通常在首次使用类时将其加载到内存中。static 变量也是在此时进行初始化的。”

变量作用域的详细介绍 - 1

“上述示例声明了 Cat 类,该类包含四个变量:a、b、s(非 static 变量)和 count(static 变量)。如果我们为此类创建几个对象(例如,三个),则对于此类的非 static 变量,每个对象都将包含自己的实例。static 变量由类的所有对象共享。从技术上讲,它甚至不在这些对象之内,因为它甚至在创建任何 Cat 对象之前既已存在。”

“如果我们声明变量 s static,则会发生以下情况:”

变量作用域的详细介绍 - 2

“好的。我想我明白了。”

“你可以使用相同的名称来声明变量吗?”

“在方法内不可以。方法内声明的所有变量都必须具有唯一的名称。方法的参数也被视为局部变量。”

“成员变量如何呢?”

“成员变量对于每个类也必须是唯一的。”

“但是有一个例外:局部变量和成员变量的名称可以相同。

“如果我们更改这样一个变量,那么名称相同的两个变量中的哪一个会被更改呢?”

“如果代码中有多个可见(可访问)变量(例如,实例变量和局部变量),则将访问局部变量。”

包含两个 count 变量的示例
class Main
{
    public int count = 0;     // 声明实例变量

    public void run()
    {
        count = 15;           // 访问实例变量
        int count = 10;       // 声明局部方法变量
        count++;             // 访问方法变量
    }
}

“此代码声明了两个 count 变量。第 3 行声明了一个实例变量,第 8 行声明了一个局部变量。”

“执行 run 方法时会发生以下情况:”

“在第 7 行,我们访问实例变量并为其赋值 15”

“在第 8 行,我们声明(创建)一个新的局部变量count。它遮罩了实例变量。方法中的所有后续代码都将看到(访问)该局部变量。”

“明白了。”

“局部变量将遮罩实例变量。换言之,局部变量是要访问的变量。但是,你也可以访问实例变量。只是这样做有点复杂。”

static(类)变量
ClassName.variableName

// 下面是一些示例:
Cat.catsCount
非 static(实例)变量
this.variableName

// 下面是一些示例:
this.catsCount

“关于 static 方法和 static 变量,你还有什么要讲的吗?”

“static 方法和变量不链接到类的对象;它们链接到类本身。如果我们创建十个 Variables 对象(请参见本级别开头的示例),我们将有十个 instanceVariable 变量(每个对象一个),并且仅有一个共享的 (static) 变量 TEXT。”

“我有一个问题。”

“static 方法和非 static 方法有什么区别?"

“我们来看一下非 static 方法的工作原理:”

代码看起来如下所示
Cat cat = new Cat();
String name = cat.getName();
cat.setAge(17);
cat.setChildren(cat1, cat2, cat3);
实际发生的情况如下
Cat cat = new Cat();
String name = Cat.getName(cat);
Cat.setAge(cat,17);
Cat.setChildren(cat, cat1, cat2, cat3);

“使用 <对象> 点 <方法名称> 调用方法时,实际上是在调用类方法,并将该对象作为第一个参数进行传递。在方法内,对象称为‘this’。方法中的所有操作都是针对此对象及其数据执行的。”

“哇!那么这就是它的工作原理了!”

“这就是 static 方法的工作原理。”

代码看起来如下所示
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount();
实际发生的情况如下
Cat cat1 = new Cat();
Cat cat2 = new Cat();
int catCount = Cat.getAllCatsCount(null);

“在调用 static 方法时,不会向它传递任何对象。换言之,‘this’等于 null。这就是 static 方法无法访问非 static 变量和方法的原因(因为它没有‘this’传递给这些方法)。”

“嗯。我想我明白了。至少明白一点了。”

“迭戈叔叔来了... 带着他的任务。”