Java中的静态变量和最终静态变量之间的差异

通常,最终静态成员,特别是变量(或静态最终当然,它们可以以任何顺序使用,而不重叠含义)广泛地与Java中的接口一起使用以定义实现类的协议行为,这意味着实现(继承)一个接口必须包含该接口的所有成员。

我无法区分最终和最终的静态成员。最后的静态成员是一个静态成员声明为final还是别的?在哪些特殊情况下应该具体使用?

静态变量或最终静态变量永远不能在方法内部在静态方法内部或在实例方法内部声明。为什么?

因此,下面的代码段不会被编译,并且如果试图编译它,编译器将发出编译时错误。

public static void main(String args[])
{
    final int a=0;  //ok

    int b=1;  //ok

    static int c=2;  //wrong

    final static int x=0;  //wrong
}
最佳答案
你正在做出许多不同概念的巨大混合。即使标题中的问题与身体中的问题不一致。

无论如何,这些是你混淆的概念:

>变量
>最终变量
>字段
>最终字段
>静态字段
>最终静态字段

关键字static仅对字段有意义,但是在代码中,您将尝试在函数中使用它,其中不能声明字段(字段是类的成员;变量在方法中声明)。

让我们尝试快速描述它们。

>变量在方法中声明,并且用作某种可变本地存储(int x; x = 5; x)
> final变量也在方法中声明,并且用作不可变的本地存储(final int y; y = 0; y; //将不会编译)。它们对于捕捉有人试图修改不应修改的东西的bug是有用的。我个人使我的局部变量和方法参数最终。此外,当您从内部的匿名类中引用它们时,它们是必需的。在某些编程语言中,唯一一种变量是不可变变量(在其他语言中,“默认”类型的变量是不可变变量) – 作为一个练习,尝试找出如何编写一个循环,指定在初始化后不允许更改任何内容的次数! (尝试,例如,解决fizzbuzz只有最终变量!)。
> fields定义对象的可变状态,并在类中声明(class x {int myField;})。
> final字段定义对象的不可变状态,在类中声明,必须在构造函数完成之前初始化(类x {final int myField = 5;})。它们不能被修改。它们在执行多线程时非常有用,因为它们具有与在线程之间共享对象相关的特殊属性(如果对象在构造函数完成后共享,则每个线程都会看到对象最终字段的正确初始化值,以及即使它与数据竞争共享)。如果你想要另一个练习,尝试使用只有最终字段,没有其他字段,没有任何变量和方法参数(显然,你被允许在构造函数中声明参数,但这一切!)再次解决fizzbuzz。
>静态字段在任何类的所有实例之间共享。你可以把它们想象成某种全局的可变存储(class x {static int globalField = 5;})。最微不足道的(通常是无用的)例子是计算一个对象的实例(即类x {static int count = 0; x(){count;}},这里构造函数每次调用时都会增加计数,即,每次使用new x()创建x的实例。注意,与最终字段不同,它们本身不是线程安全的;换句话说,如果你从不同的线程实例化,你肯定会得到一个错误计数的x的实例与上面的代码;为了使它正确,你必须添加一些同步机制或使用一些专门的类来实现这个目的,但这是另一个问题(实际上,它可能是整本书的主题)。
> final static fields是全局常量(类MyConstants {public static final double PI = 3.1415926535897932384626433;})。

还有许多其他微妙的特性(如:编译器可以自由地将对最终静态字段的引用替换为它们的值,这使得反射在这样的字段上无用;最终字段实际上可能会被反射修改,但这是非常容易出错的;等等),但我想说你还有很长的路要走,进一步挖掘。

最后,还有可能用于字段的其他关键字,如瞬态,易失性和访问级别(public,protected,private)。但这是另一个问题(实际上,如果你想问他们,许多其他问题,我会说)。

转载注明原文:Java中的静态变量和最终静态变量之间的差异 - 代码日志