1.常量

许多其他编程语言都有常量,即值不能更改的变量。通常,它们用于表示某种基本事物,例如Pi一年中的月份数或天数。也就是说,原则上,如果程序员认为有必要这样做,他或她可以将任何变量设为常量。

那么在Java中如何声明一个不可变变量(常量)呢?为此有一个特殊的关键字:final. 创建不可变变量看起来与创建普通变量一样。唯一的区别是在变量类型之前你需要写单词final,像这样:

final Type name = value;

如果您尝试为final变量分配不同的值,那么您的程序将无法编译。

final声明变量时必须对其进行初始化(必须为其分配值)。此规则有一个例外:您可以将静态类变量的初始化移动到构造函数中。但是您将在第 10 级中了解到这一点

final为了减少关键字的数量,Java 开发人员不仅仅将关键字用于声明常量。final也可以应用于方法甚至类。声明为 as 的方法final不能被覆盖,声明为 as 的类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;
}


2.可变阴影

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

但您可能不知道:实例变量和局部方法变量可以同名。

例子:

代码 可变可见性
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
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.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



3.for循环内的变量

还有一个小而有趣的事实。

还有一个变量以特殊方式声明的地方——在循环for

您可能还记得,for循环通常在括号中有一个计数器变量。这个变量的可见性是什么?毕竟,它不在循环体内。是整个方法吗?或不?

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