您正在将许多不同的概念混合在一起。甚至标题中的问题也与正文中的问题不符。
无论如何,这些是您正在混淆的概念:
- 变数
- 最终变量
- 领域
- 最终领域
- 静态场
- 最终静态场
该关键字
static仅对字段有意义,但是在您显示的代码中,您试图在无法声明字段的函数中使用它(字段是类的成员;变量在方法中声明)。
让我们尝试快速描述它们。
变量 在方法中声明,并用作某种 可变的本地存储 (
int x; x = 5; x++
)final变量 也在方法中声明,并用作 不可变的本地存储 (
final int y; y = 0; y++; // won't compile
)。它们对于发现某些人会尝试修改不应修改的错误很有用。我个人将大部分局部变量和方法参数作为参数final
。另外,当您从内部匿名类引用它们时,它们是必需的。在某些编程语言中,唯一的变量类型是不可变变量(在其他语言中,“默认”类型的变量是不可变变量)-作为练习,请尝试弄清楚如何编写一个循环来运行变量。指定的次数,不允许在初始化后更改任何内容!(例如,尝试仅使用最终变量解决 fizzbuzz !)。字段 定义了 对象 的 可变状态 ,并在类(
class x { int myField; })中声明。final字段 定义了 对象 的 不变状态 ,它们在类中声明,并且必须在构造函数完成(
class x { final int myField = 5; })之前初始化。它们不能被修改。它们在执行多线程处理时非常有用,因为它们具有与线程之间共享对象有关的特殊属性(如果在构造函数完成后共享对象,则可以确保每个线程都会看到对象的final字段的正确初始化值,并且即使它与数据竞争共享)。如果您想进行其他练习,请尝试仅使用final字段而不使用其他字段,而不使用任何变量或方法参数来再次解决 fizzbuzz (显然,您可以在构造函数中声明参数,仅此而已!)。静态字段 的 任何类的所有实例共享 。您可以将它们视为某种全局可变存储(
class x { static int globalField = 5; })。最琐碎的(通常是无用的)示例是对对象的实例进行计数(即,class x { static int count = 0; x() { count++; } }在此构造函数每次调用对象时(即,每次x
使用with 创建实例时new x()
)都增加计数。注意,与final字段不同,它们本质上不是线程安全的;换句话说,您肯定会得到错误的实例计数x
如果从不同的线程实例化,请使用上面的代码;为了使其正确,您必须为此添加一些同步机制或使用一些专门的类,但这是另一个问题(实际上,它可能是整本书的主题)。最终的静态字段 是 全局常量 (
class MyConstants { public static final double PI = 3.1415926535897932384626433; })。
还有许多其他细微的特性(例如:编译器可以自由地将对最终静态字段的引用直接替换为其值,这使反射在此类字段上无用;最终字段实际上可能会被反射修改,但这很容易出错;并且等等),但我想说您还有很长的路要走。
最后,也有可能与领域,如可使用其他关键词
transient,
volatile以及访问级别(
public,
protected,
private)。但这是另一个问题(实际上,如果您要询问这些问题,我会说很多其他问题)。



