简体   繁体   English

Java中静态变量和最终静态变量之间的区别

[英]Difference between a static and a final static variable in Java

Generally, final static members especially, variables (or static final of course, they can be used in either order without overlapping the meaning) are extensively used with interfaces in Java to define a protocol behavior for the implementing class which implies that the class that implements (inherits) an interface must incorporate all of the members of that interface.通常,特别是 final 静态成员,变量(当然也可以是静态 final,它们可以按任意顺序使用而不会重叠含义)广泛用于 Java 中的接口,以定义实现类的协议行为,这意味着实现类(继承)一个接口必须包含该接口的所有成员。


I'm unable to differentiate between a final and a final static member.我无法区分最终最终静态成员。 The final static member is the one which is a static member declared as final or something else?最后一个静态成员是声明为 final 的静态成员还是其他什么? In which particular situations should they be used specifically?应该在哪些特定情况下专门使用它们?


A static variable or a final static variable can never be declared inside a method neither inside a static method nor inside an instance method.永远不能在方法内部声明静态变量或最终静态变量,既不能在静态方法内部,也不能在实例方法内部。 Why?为什么?

The following segment of code accordingly, will not be compiled and an compile-time error will be issued by the compiler, if an attempt is made to compile it.相应地,以下代码段将不会被编译,并且如果尝试编译它,编译器将发出编译时错误。

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
}

You are making a huge mix of many different concepts.您正在大量混合许多不同的概念。 Even the question in the title does not correspond to the question in the body.甚至标题中的问题也不对应正文中的问题。

Anyways, these are the concepts you are mixing up:无论如何,这些是您正在混淆的概念:

  • variables变量
  • final variables最终变量
  • fields领域
  • final fields最终字段
  • static fields静态字段
  • final static fields最终静态字段

The keyword static makes sense only for fields, but in the code you show you are trying to use it inside a function, where you cannot declare fields (fields are members of classes; variables are declared in methods).关键字static仅对字段有意义,但在您展示的代码中,您试图在函数中使用它,在该函数中您不能声明字段(字段是类的成员;变量在方法中声明)。

Let's try to rapidly describe them.让我们尝试快速描述它们。

  1. variables are declared in methods, and used as some kind of mutable local storage ( int x; x = 5; x++ )变量在方法中声明,并用作某种可变的本地存储int x; x = 5; x++

  2. final variables are also declared in methods, and are used as an immutable local storage ( final int y; y = 0; y++; // won't compile ). final 变量也在方法中声明,并用作不可变的本地存储final int y; y = 0; y++; // won't compile )。 They are useful to catch bugs where someone would try to modify something that should not be modified.它们对于捕获某人试图修改不应修改的内容的错误很有用。 I personally make most of my local variables and methods parameters final .我个人将大部分局部变量和方法参数final Also, they are necessary when you reference them from inner, anonymous classes.此外,当您从内部匿名类引用它们时,它们是必需的。 In some programming languages, the only kind of variable is an immutable variable (in other languages, the "default" kind of variable is the immutable variable) -- as an exercise, try to figure out how to write a loop that would run an specified number of times when you are not allowed to change anything after initialization!在某些编程语言中,唯一一种变量是不可变变量(在其他语言中,“默认”类型的变量是不可变变量)——作为练习,尝试找出如何编写一个循环来运行初始化后不允许更改任何内容的指定次数! (try, for example, to solve fizzbuzz with only final variables!). (例如,尝试仅使用最终变量解决fizzbuzz 问题!)。

  3. fields define the mutable state of objects , and are declared in classes ( class x { int myField; } ).字段定义了对象可变状态,并在类中声明( class x { int myField; } )。

  4. final fields define the immutable state of objects , are declared in classes and must be initialized before the constructor finishes ( class x { final int myField = 5; } ). final 字段定义了对象不可变状态,在类中声明并且必须在构造函数完成之前初始化( class x { final int myField = 5; } )。 They cannot be modified.它们不能被修改。 They are very useful when doing multithreading, since they have special properties related to sharing objects among threads (you are guaranteed that every thread will see the correctly initialized value of an object's final fields, if the object is shared after the constructor has finished, and even if it is shared with data races).它们在执行多线程时非常有用,因为它们具有与线程之间共享对象相关的特殊属性(您可以保证每个线程都会看到对象的最终字段的正确初始化值,如果在构造函数完成后共享对象,并且即使它与数据竞争共享)。 If you want another exercise, try to solve fizzbuzz again using only final fields, and no other fields, not any variables nor method parameters (obviously, you are allowed to declare parameters in constructors, but thats all!).如果你想要另一个练习,尝试只使用 final 字段再次解决fizzbuzz ,没有其他字段,没有任何变量或方法参数(显然,你可以在构造函数中声明参数,但仅此而已!)。

  5. static fields are shared among all instances of any class .静态字段在任何类的所有实例之间共享 You can think of them as some kind of global mutable storage ( class x { static int globalField = 5; } ).您可以将它们视为某种全局可变存储( class x { static int globalField = 5; } )。 The most trivial (and usually useless) example would be to count instances of an object (ie, class x { static int count = 0; x() { count++; } } , here the constructor increments the count each time it is called, ie, each time you create an instance of x with new x() ).最简单(通常也无用)的例子是计算对象的实例数(即class x { static int count = 0; x() { count++; } } ,这里构造函数每次调用时都会增加计数,即,每次您使用new x()创建x的实例时。 Beware that, unlike final fields, they are not inherently thread-safe;请注意,与 final 字段不同,它们本质上不是线程安全的; in other words, you will most certainly get a wrong count of instances of x with the code above if you are instantiating from different threads;换句话说,如果您从不同的线程进行实例化,那么使用上面的代码肯定会得到错误的x实例计数; to make it correct, you'd have to add some synchronization mechanism or use some specialized class for this purpose, but that is another question (actually, it might be the subject of a whole book).为了使它正确,您必须为此目的添加一些同步机制或使用一些专门的类,但这是另一个问题(实际上,它可能是整本书的主题)。

  6. final static fields are global constants ( class MyConstants { public static final double PI = 3.1415926535897932384626433; } ). final 静态字段全局常量class MyConstants { public static final double PI = 3.1415926535897932384626433; } )。

There are many other subtle characteristics (like: compilers are free to replace references to a final static field to their values directly, which makes reflection useless on such fields; final fields might actually be modified with reflection, but this is very error prone; and so on), but I'd say you have a long way to go before digging in further.还有许多其他微妙的特性(例如:编译器可以自由地将最终静态字段的引用直接替换为其值,这使得反射对此类字段无用;最终字段实际上可能会被反射修改,但这很容易出错;和等等),但我想说在进一步挖掘之前你还有很长的路要走。

Finally, there are also other keywords that might be used with fields, like transient , volatile and the access levels ( public , protected , private ).最后,还有其他关键字可以与字段一起使用,例如transientvolatile和访问级别( publicprotectedprivate )。 But that is another question (actually, in case you want to ask about them, many other questions, I'd say).但这是另一个问题(实际上,如果您想询问他们,还有许多其他问题,我会说)。

Static members are those which can be accessed without creating an object.静态成员是那些无需创建对象即可访问的成员。 This means that those are class members and nothing to do with any instances.这意味着那些是类成员,与任何实例无关。 and hence can not be defined in the method.因此不能在方法中定义。

Final in other terms, is a constant (as in C).换句话说final是一个常数(如在 C 中)。 You can have final variable inside the method as well as at class level.您可以在方法内部以及类级别拥有最终变量。 If you put final as static it becomes "a class member which is constant" .如果你把 final 设为静态,它就会变成“一个常量的类成员”

final keyword simply means "this cannot be changed".It can be used with both fields and variables in a method.When a variable is declared final an attempt to change the variable will result to a compile-time error.For example if i declare a variable as final int x = 12; final 关键字仅表示“无法更改”。它可以与方法中的字段和变量一起使用。当变量被声明为 final 时,尝试更改该变量将导致编译时错误。例如,如果我声明作为最终 int x = 12 的变量; trying to increment x that is (++x) will produce an error.In short with primitives final makes a value a constant.试图增加 x 即 (++x) 会产生一个错误。简而言之,用 final 使一个值成为一个常数。 On the other hand static can only be applied with fields but not in methods.A field that is final static has only one piece of storage.final shows that it is a constant(cannot be changed), static shows it is only one.另一方面,静态只能应用于字段,不能应用于方法。最终静态的字段只有一个存储空间。最终表示它是一个常量(不能更改),静态表示它只有一个。

In Java, a static variable is one that belongs to class rather than the object of a class, different instances of the same class will contain the same static variable value.在Java中,静态变量是属于类而不是类的对象,同一个类的不同实例将包含相同的静态变量值。

A final variable is one that once after initialized ,after the instantiation of a class (creation of an object) cannot be altered in the program.最终变量是一个在初始化后,在类的实例化(创建一个对象)之后不能在程序中更改的变量。 However this differ from objects if a different value is passed post creation of another object of the same class.但是,如果在创建同一类的另一个对象后传递不同的值,则这与对象不同。

final static means that the variable belongs to the class as well as cannot be change once initialized. final static 意味着该变量属于该类,并且一旦初始化就不能更改。 So it will be accessible to the same value throughout different instances of the same class.因此,可以在同一类的不同实例中访问相同的值。

I'm unable to differentiate between a final and a final static member.我无法区分最终和最终静态成员。 The final static member is the one which is a static member declared as final or something else?最后一个静态成员是声明为 final 的静态成员还是其他什么? In which particular situations should they be used specifically?应该在哪些特定情况下专门使用它们?

Use a final static when you want it to be static .当您希望它是static时,请使用final static static Use a final (non-static) when you don't want it to be static .当您不希望它是static时,请使用final (非静态)。

A static variable or a final static variable can never be declared inside a method neither inside a static method nor inside an instance method.永远不能在方法内部声明静态变量或最终静态变量,既不能在静态方法内部,也不能在实例方法内部。 Why?为什么?

Design decision.设计决策。 There's just no way to answer that without asking James Gosling.如果不询问 James Gosling,就无法回答这个问题。

The following segment of code accordingly, will not be compiled and an compile-time error will be issued by the compiler, if an attempt is made to compile it.相应地,以下代码段将不会被编译,并且如果尝试编译它,编译器将发出编译时错误。

Because it violates the rule you just described.因为它违反了你刚才描述的规则。

只是在@Bruno Reis 的答案中添加一个次要信息,我试图完成答案,因为他谈到了在构造函数结束之前初始化最终字段的重要条件,最终静态字段也必须在静态块执行完成之前初始化.

你不能在静态块中声明静态字段,静态字段只能属于一个类,因此编译器错误。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM