常量

“朋友,你知道在 Java 中并不是所有的变量都可以改变吗?”

“怎么样,Kim?的确,‘可变’这个词本身就代表着变化。”

“这一点毫无疑问。与许多其他编程语言一样,Java 具有常量,即其值无法更改的变量。而‘常量’这个词本身就是恒常性。”

“它们是做什么用的?”

“通常,它们用于某种基本事物,例如Pi一年中几个月的天数或天数。也就是说,原则上,程序员可以将任何变量设为常量,如果他或她决定这样做的话所以是必要的。”

“你的意思是像名字、汽车的颜色或星期几的名字?”

“你的想法是正确的。任何不应该改变的东西。”

“这些常量在 Java 中是什么样子的?”

“Java 有一个特殊的关键字:final。创建一个不可变变量看起来与创建一个普通变量一样。唯一的区别是在变量类型之前你需要写这个词final,如下所示:

final Type name = value;

“如果您创建一个常量然后尝试为其分配不同的值,会发生什么情况?”

“这是正确的问题!正确的答案是:如果你试图为变量分配不同的值final,那么你的程序根本无法编译。”

“如果你声明了一个final变量但没有给它赋值呢?”

“这样做没有意义,所以在 Java 中也是不允许的。一个final变量必须在声明时初始化,也就是说,你必须给它赋值。这个规则有一个例外:你可以移动初始化一个静态类变量到一个构造函数中。但是你稍后会了解到这一点。

“也就是说,并不是所有的东西都是final常量。为了减少关键字的数量,Java 开发人员使用这个词final不仅仅用于声明常量。final还可以应用于方法甚至类。声明为的方法final不能被覆盖,而类声明为final不能继承。”

“呃……覆盖?继承?你现在说的是什么语言?”

“面向对象编程的语言。你很快就会掌握它。在那之前,尽情享受美丽的术语吧。”

“好的。所以,final可以放在变量、类和方法之前,这个关键字使它们在某种意义上是不可变的?”

“是的。此外,final修饰符可以添加在任何变量之前:局部变量、方法参数、类字段和静态类变量。

“这里有一件重要的事情要记住:final在变量名之前只是为了防止对该变量进行任何更改。如果变量存储了对对象的引用,那么该对象仍然可以更改。”

“我不太明白。”

“你很快就会明白的。这是一个例子:

final int[] data = {1, 2, 3, 4, 5, 6};

data = {6, 7, 8, 9};

data[0] = 0;
data[1] = 0;
data[2] = 0;
我们创建一个数组。

这是不允许的:变量data声明为final.

但你可以做到这一点。
还有这个。

“知道了。这很棘手。”

全局常量

“你认为全局常数是什么?”

“我猜全局常量可能就像全局变量一样,只是常量?”

“没错。如果你需要在你的程序中声明全局常量,创建静态类变​​量,并使它们publicfinal。这种变量的名称有一种特殊的风格:它们全部用大写字母书写,下划线用于分开的话。

例子:

class Solution
{
   public static final String SOURCE_ROOT = "c:\\projects\\my\\";
   public static final int DISPLAY_WIDTH = 1024;
   public static final int DISPLAY_HEIGHT = 768;
}

可变阴影

“正如我之前所说,你不能在一个方法中创建多个同名的局部变量。在不同的方法中,你可以。”

“我知道!”

“但是您可能不知道的是,类中的变量和方法中的局部变量很可能具有相同的名称。

例子:

代码 可变可见性
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     sum = sum + data;
     int sum = data * 2;
     count++;
   }
}

count, sum
count, sum
count, sum
count, sum
count, sum
count, sum, data
count, sum, data
count, sum, data
count, sum, data
count, sum

“在add方法中,我们声明了一个名为 的局部变量sum。在方法结束之前,它会隐藏(或屏蔽sum实例变量。”

“嗯......我会说在某种意义上这是预期的行为。”

“但这不是故事的结局。事实证明,如果一个实例变量被局部变量遮蔽,仍然有一种方法可以在方法中引用该实例变量。我们通过在其名称前写关键字来this实现:

this.name

“这是成功解决名称冲突的示例:

代码 可变可见性
public class Solution
{
   public int count = 0;
   public int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     this.sum = this.sum + data;
     count++;
   }
}

this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum
this.count, this.sum, data
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum, data, sum
this.count, this.sum

和变量在count任何sum地方都可以使用或不使用this关键字。sum在局部变量覆盖实例变量的行中sumsum只能使用this关键字访问实例变量。

“显然,我需要练习这个。”

“你会处理的。”

“如果一个静态类变量被遮蔽而不仅仅是一个(非静态)实例变量怎么办?你不能通过它访问它this?”

“你是对的。这个关键字不起作用。你需要通过类名来引用它:

ClassName.name

例子:

代码 可变可见性
public class Solution
{
   public static int count = 0;
   public static int sum = 0;

   public void add(int data)
   {
     int sum = data * 2;
     Solution.sum = Solution.sum + data;
     count++;
   }
}

Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum
Solution.count, Solution.sum, data
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum, data, sum
Solution.count, Solution.sum

“请注意:无论是否使用类名作为前缀,您都可以在任何地方访问count和静态变量。在局部变量隐藏实例变量的那些行中,只有在作为前缀使用时才能访问类变量。sumSolutionsumsumsumSolution

for循环内的变量

“还有一个小但有趣的事实。还有一个地方可以用特殊的方式声明变量——我说的是在循环内部for ” 通常,循环在括号中for有一个变量。counter这个变量的可见性是什么?毕竟,它不在循环体内。是整个方法吗?或不?”

for“我已经听说过这件事。据我了解,在循环标头中声明的变量仅在循环体循环标头for中可见。”

“干得好,阿米戈。但是,还是看一个例子来强化这个材料:

代码 可变可见性
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a

“所以你是说,在我的代码中,我可以用一个同名的计数器变量一个接一个地写几个循环,不会有问题吗?”

“不会有问题的。看这里:

代码 可变可见性
public static void main(String[] args)
{
   int a = 0;

   for (int i = 0; i < 10; i++)
   {
     System.out.println(i);
   }

   for (int i = 0; i < 10; i--)
   {
     System.out.println(i);
   }

   System.out.println("end");
}


a
a
a, i
a, i
a, i
a
a
a, i
a, i
a, i
a
a
a