通常,最终的静态成员,尤其是变量(或者当然,静态最终,它们可以按顺序使用而不重叠含义)与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
}
Run Code Online (Sandbox Code Playgroud)
Bru*_*eis 120
你正在混合许多不同的概念.甚至标题中的问题也不符合正文中的问题.
无论如何,这些是你混淆的概念:
该关键字static仅对字段有意义,但在您展示的代码中,您尝试在函数内使用它,您无法声明字段(字段是类的成员;变量在方法中声明).
让我们试着快速描述它们.
变量在方法中声明,并用作某种可变的本地存储(int x; x = 5; x++)
最终变量也在方法中声明,并用作不可变的本地存储(final int y; y = 0; y++; // won't compile).它们可用于捕获有人试图修改不应修改的内容的错误.我亲自制作了大部分的局部变量和方法参数final.此外,当您从内部匿名类引用它们时,它们是必需的.在某些编程语言中,唯一的变量是不可变变量(在其他语言中,"默认"类型的变量是不可变变量) - 作为练习,尝试弄清楚如何编写一个循环来运行初始化后不允许更改任何内容时指定的次数!(例如,尝试用最终变量来解决fizzbuzz!).
fields定义对象的可变状态,并在classes(class x { int myField; })中声明.
final字段定义对象的不可变状态,在类中声明,并且必须在构造函数完成(class x { final int myField = 5; })之前初始化.它们无法修改.它们在执行多线程时非常有用,因为它们具有与线程间共享对象相关的特殊属性(如果在构造函数完成后共享对象,则保证每个线程都能看到对象的最终字段的正确初始化值,并且即使它与数据竞争共享).如果你想要另一个练习,尝试仅使用final字段再次解决fizzbuzz,没有其他字段,没有任何变量或方法参数(显然,你可以在构造函数中声明参数,但这就是全部!).
静态字段的任何类的所有实例共享.您可以将它们视为某种全局可变存储(class x { static int globalField = 5; }).最简单(通常是无用的)示例是计算对象的实例(即,class x { static int count = 0; x() { count++; } }这里构造函数在每次调用时递增计数,即每次创建xwith 的实例时new x()).请注意,与最终字段不同,它们本身并不是线程安全的; 换句话说,x如果你从不同的线程实例化,你肯定会得到错误的上述代码实例数; 为了使它正确,你必须添加一些同步机制或为此目的使用一些专门的类,但这是另一个问题(实际上,它可能是整本书的主题).
最终的静态字段是全局常量(class MyConstants { public static final double PI = 3.1415926535897932384626433; }).
还有许多其他微妙的特性(例如:编译器可以直接将对最终静态字段的引用替换为它们的值,这使得反射在这些字段上无用;最终字段实际上可能会被反射修改,但这非常容易出错;并且所以),但我会说你还有很长的路要走,才能进一步深入挖掘.
最后,也有可能与领域,如可使用其他关键词transient,volatile以及访问级别(public,protected,private).但这是另一个问题(实际上,如果您想询问它们,还有许多其他问题,我会说).
Nav*_*oft 27
静态成员是可以在不创建对象的情况下访问的成员.这意味着那些是类成员,与任何实例无关.因此不能在方法中定义.
在其他方面,最终是一个常数(如在C中).您可以在方法内部以及类级别中拥有最终变量.如果你把final作为静态变成"一个恒定的类成员".
| 归档时间: |
|
| 查看次数: |
80451 次 |
| 最近记录: |