私有最终静态属性与私有最终属性
在Java中,有什么区别:
private final static int NUMBER = 10;
和
private final int NUMBER = 10;
都是private
和final
,区别在于static
属性。
什么更好?为什么?
In Java, what's the difference between:
private final static int NUMBER = 10;
and
private final int NUMBER = 10;
Both are private
and final
, the difference is the static
attribute.
What's better? And why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(22)
一般来说,
static
表示“与类型本身相关,而不是与该类型的实例相关”。这意味着您可以引用静态变量,而无需创建该类型的实例,并且引用该变量的任何代码都引用完全相同的数据。将此与实例变量进行比较:在这种情况下,类的每个实例都有一个独立版本的变量。例如:
打印出 10:
y.instanceVariable
和x.instanceVariable
是分开的,因为x
和y
指代不同的对象。您可以通过引用来引用静态成员,尽管这样做不是一个好主意。如果我们这样做:
那么就会打印出 20 - 只有一个变量,而不是每个实例一个。如果将其写为:
这使得行为更加明显。现代 IDE 通常会建议将第二个列表更改为第三个列表。
没有理由使用内联声明来初始化如下所示的值,因为每个实例都有自己的
NUMBER
但始终具有相同的值(不可变并使用文字初始化)。这与所有实例只有一个final static
变量相同。因此,如果它无法更改,则每个实例拥有一份副本就没有意义。
但是,如果在这样的构造函数中初始化,那就有意义了:
现在,对于
MyClass
的每个实例,我们可以拥有不同但不可变的number
值。In general,
static
means "associated with the type itself, rather than an instance of the type."That means you can reference a static variable without having ever created an instances of the type, and any code referring to the variable is referring to the exact same data. Compare this with an instance variable: in that case, there's one independent version of the variable per instance of the class. So for example:
prints out 10:
y.instanceVariable
andx.instanceVariable
are separate, becausex
andy
refer to different objects.You can refer to static members via references, although it's a bad idea to do so. If we did:
then that would print out 20 - there's only one variable, not one per instance. It would have been clearer to write this as:
That makes the behaviour much more obvious. Modern IDEs will usually suggest changing the second listing into the third.
There is no reason to have an inline declaration initializing the value like the following, as each instance will have its own
NUMBER
but always with the same value (is immutable and initialized with a literal). This is the same than to have only onefinal static
variable for all instances.Therefore if it cannot change, there is no point having one copy per instance.
But, it makes sense if is initialized in a constructor like this:
Now, for each instance of
MyClass
, we can have a different but immutable value ofnumber
.静态变量在应用程序的整个生命周期中都保留在内存中,并在类加载期间初始化。每次构造
新
对象时都会初始化非静态
变量。通常最好使用:Why?这减少了每个实例的内存占用。它也可能有利于缓存命中。这是有道理的:
static
应该用于在某种类型(又名class
)的所有实例(又名对象)之间共享的东西。A
static
variable stays in the memory for the entire lifetime of the application, and is initialised during class loading. A non-static
variable is being initialised each time you construct anew
object. It's generally better to use:Why? This reduces the memory footprint per instance. It possibly is also favourable for cache hits. And it just makes sense:
static
should be used for things that are shared across all instances (a.k.a. objects) of a certain type (a.k.a.class
).对于final,可以在初始化时在运行时为其分配不同的值。
例如
,因此每个实例都有不同的字段a值。
对于静态最终,所有实例共享相同的值,并且在首次初始化后无法更改。
For final, it can be assigned different values at runtime when initialized.
For example
Thus each instance has different value of field a.
For static final, all instances share the same value, and can't be altered after first initialized.
static 表示“与类相关”;如果没有它,变量将与类的每个实例相关联。如果它是静态的,则意味着内存中只有一个;如果没有,您创建的每个实例都会有一个。 static 意味着只要类被加载,变量就会保留在内存中;如果没有它,变量可以在其实例存在时被GC。
static means "associated with the class"; without it, the variable is associated with each instance of the class. If it's static, that means you'll have only one in memory; if not, you'll have one for each instance you create. static means the variable will remain in memory for as long as the class is loaded; without it, the variable can be gc'd when its instance is.
阅读答案后,我发现没有真正的测试能够真正切中要害。这是我的 2 美分:
第一个对象的结果:
第二个对象的结果:
结论:
因为我认为 java 在原始类型和其他类型之间有所区别。 Java 中的原始类型始终被“缓存”,字符串文字(不是新的 String 对象)也是如此,因此静态和非静态成员之间没有区别。
但是,如果非静态成员不是基本类型的实例,则它们会出现内存重复。
将 valueStatic 的值更改为 10 甚至会更进一步,因为 Java 将为两个 int 变量提供相同的地址。
Reading the answers I found no real test really getting to the point. Here are my 2 cents :
Results for first object :
Results for 2nd object :
Conclusion :
As I thought java makes a difference between primitive and other types. Primitive types in Java are always "cached", same for strings literals (not new String objects), so no difference between static and non-static members.
However there is a memory duplication for non-static members if they are not instance of a primitive type.
Changing value of valueStatic to 10 will even go further as Java will give the same addresses to the two int variables.
虽然其他答案似乎很清楚地表明通常没有理由使用非静态常量,但我找不到任何人指出可以在其常量变量上拥有不同值的各种实例。
考虑以下示例:
创建 TestClass 的三个实例将打印相同的随机值三次,因为只生成一个值并将其存储到静态常量中。
但是,当尝试以下示例时:
创建 TestClass 的三个实例现在将打印三个不同的随机值,因为每个实例都有其自己的随机生成的常量值。
我想不出在不同实例上使用不同常量值的任何情况确实有用,但我希望这有助于指出静态和非静态决赛之间存在明显的区别。
While the other answers seem to make it pretty clear that there is generally no reason to use non-static constants, I couldn't find anyone pointing out that it is possible to have various instances with different values on their constant variables.
Consider the following example:
Creating three instances of TestClass would print the same random value three times, since only one value is generated and stored into the static constant.
However, when trying the following example instead:
Creating three instances of TestClass would now print three different random values, because each instance has its own randomly generated constant value.
I can't think of any situation where it would be really useful to have different constant values on different instances, but I hope this helps pointing out that there is a clear difference between static and non-static finals.
很少,和 static
没有太大区别,因为它们都是常量。对于大多数类数据对象来说,静态意味着与类本身相关的东西,无论使用 new 创建了多少个对象,都只有一份副本。
由于它是一个常量,因此它实际上可能不会存储在类或实例中,但编译器仍然不会让您从静态方法访问实例对象,即使它知道它们是什么。如果不将其静态化,反射 API 的存在可能还需要一些无意义的工作。
very little, and static
There isn't much difference as they are both constants. For most class data objects, static would mean something associated with the class itself, there being only one copy no matter how many objects were created with new.
Since it is a constant, it may not actually be stored in either the class or in an instance, but the compiler still isn't going to let you access instance objects from a static method, even if it knows what they would be. The existence of the reflection API may also require some pointless work if you don't make it static.
正如 Jon 所说,静态变量也称为类变量,是跨类实例存在的变量。
我在此处找到了一个示例:
程序的输出如下:
正如我们在这个例子中看到的,每个对象都有自己的类变量副本。
As already Jon said, a static variable, also referred to as a class variable, is a variable which exists across instances of a class.
I found an example of this here:
Output of the program is given below:
As we can see in this example each object has its own copy of class variable.
根据我所做的测试,静态最终变量与最终(非静态)变量不同!最终(非静态)变量可能因对象而异!但这只是在构造函数内进行初始化的情况下! (如果它没有从构造函数初始化,那么它只是浪费内存,因为它为每个创建的对象创建无法更改的最终变量。)
例如:
屏幕上显示的是:
关于对象:A@addbf1
决赛:14
静态决赛:5
关于对象:A@530daa
决赛:21
静态决赛:5 名
匿名信息技术一年级学生,希腊
From the tests i have made, static final variables are not the same with final(non-static) variables! Final(non-static) variables can differ from object to object!!! But that's only if the initialization is made within the constructor! (If it is not initialized from the constructor then it is only a waste of memory as it creates final variables for every object that is created that cannot be altered.)
For example:
What shows up on screen is:
About Object: A@addbf1
Final: 14
Static Final: 5
About Object: A@530daa
Final: 21
Static Final: 5
Anonymous 1st year IT student, Greece
除了乔恩的回答之外,如果您使用静态最终,它将表现为一种“定义”。一旦编译使用它的类,它将在编译后的 .class 文件中被烧毁。
请在此处查看我的帖子。
对于您的主要目标:如果您在类的不同实例中不以不同的方式使用 NUMBER,我建议使用 Final 和 static。
(您只需记住,不要在不考虑可能出现的问题(如我的案例研究描述的问题)的情况下复制已编译的类文件。大多数情况下不会发生这种情况,不用担心:))
要向您展示如何在实例中使用不同的值,请检查以下代码:
Furthermore to Jon's answer if you use static final it will behave as a kind-of "definition". Once you compile the class which uses it, it will be in the compiled .class file burnt.
Check my thread about it here.
For your main goal: If you don't use the NUMBER differently in the different instances of the class i would advise to use final and static.
(You just have to keep in mind to not to copy compiled class files without considering possible troubles like the one my case study describes. Most of the cases this does not occur, don't worry :) )
To show you how to use different values in instances check this code:
这是我的两分钱:
示例:
关键是变量和函数可以返回不同的值。因此最终变量可以分配不同的值。
Here is my two cents:
Example:
The key is that variables and functions can return different values.Therefore final variables can be assigned with different values.
private static final 将被视为常量,并且该常量只能在该类中访问。由于包含关键字 static,因此该值对于该类的所有对象都是恒定的。
私有最终变量值将类似于每个对象的常量。
您可以参考 java.lang.String 或查找下面的示例。
//输出:
private static final will be considered as constant and the constant can be accessed within this class only. Since, the keyword static included, the value will be constant for all the objects of the class.
private final variable value will be like constant per object.
You can refer the java.lang.String or look for the example below.
//Output:
这只是另一个简单的例子来了解 static、static final、final 变量的用法。代码注释有正确的解释。
Just Another simple example to understand the usage of static, static final, final variables. Code comments have the proper explanation.
由于类中的变量被声明为 Final 并在同一命令中初始化,
绝对没有理由不将其声明为静态,因为无论实例如何,它都将具有相同的值。因此,所有实例都可以共享一个值的相同内存地址,从而无需为每个实例创建新变量,并通过共享 1 个公共地址来节省内存,从而节省了处理时间。
Since a variable in a class is declared as final AND initialised in the same command,
there is absolutely no reason to not declare it as static, since it will have the same value no matter the instance. So, all instances can share the same memory address for a value, thus saving processing time by eliminating the need to create a new variable for each instance and saving memory by sharing 1 common address.
静态成员在所有类实例和类本身上都是相同的成员。
非静态是针对每个实例(对象)的,因此在您的具体情况中,如果您不放置静态,则会浪费内存。
The static one is the same member on all of the class instances and the class itself.
The non-static is one for every instance (object), so in your exact case it's a waste of memory if you don't put static.
如果您将此变量标记为静态,那么如您所知,您将需要静态方法再次访问这些值,如果您已经考虑仅在静态方法中使用这些变量,这将很有用。如果是这样的话,那么这将是最好的。
然而,您现在可以将该变量设为公共,因为没有人可以像“System.out”一样修改它,这又取决于您的意图和您想要实现的目标。
If you mark this variable static then as you know, you would be requiring static methods to again access these values,this will be useful if you already think of using these variables only in static methods. If this is so then this would be the best one.
You can however make the variable now as public since no one can modify it just like "System.out", it again depends upon your intentions and what you want to achieve.
假设该类不会有多个实例,那么哪一个实例占用更多内存:
private static final int ID = 250;
或者
私有最终 int ID = 250;
我知道静态将引用内存中只有一份副本的类类型,而非静态将位于每个实例变量的新内存位置。然而,在内部,如果我们只比较同一个类的 1 个实例(即不会创建超过 1 个实例),那么 1 个静态最终变量使用的空间是否有任何开销?
Lets say if the class will not have more than one instance ever, then which one takes more memory:
private static final int ID = 250;
or
private final int ID = 250;
I've understood that static will refer to the class type with only one copy in the memory and non static will be in a new memory location for each instance variable. However internally if we just compare 1 instance of the same class ever (i.e. more than 1 instance would not be created), then is there any overhead in terms of space used by 1 static final variable?
静态变量属于类(这意味着所有对象共享该变量)。非静态变量属于每个对象。
正如你在上面的例子中看到的,对于“final int”,我们可以为类的每个实例(对象)分配我们的变量,但是对于“static final int”,我们应该在类中分配一个变量(静态变量属于该类) )。
Static variable belongs to the class (which means all the objects share that variable). Non static variable belongs to each objects.
As you can see above example, for "final int" we can assign our variable for each instance (object) of the class, however for "static final int", we should assign a variable in the class (static variable belongs to the class).
如果您使用静态,则变量的值在所有实例中都将相同,如果在一个实例中更改,其他实例也会更改。
If you use static the value of the variable will be the same throughout all of your instances, if changed in one instance the others will change too.
Final:一旦分配了final变量,它总是包含相同的值。
无论变量是否是静态的
static:对于在内存中初始化一次的所有实例来说,它只是一个变量
Final: Once a final variable has been assigned, it always contains the same value.
wherever the variable is static or not
static: it will be only one variable for all instances initialized one time in Memory
这可能有帮助
This might help
“Static”关键字使类的属性可变,而不是类的单个实例。该变量将有一个副本,在该类的所有实例之间共享。静态变量状态的任何更改都将反映在所有实例中。将final添加到static中,我们得到一个在类加载时已经被一次性初始化的变量,并且以后不能被该类的任何实例更改。静态最终变量需要在声明时初始化,否则会出现编译时错误。
就私有实例字段而言,它指的是类的对象/实例的属性/状态。类的每个实例/对象都有自己的实例变量副本。当实例变量被声明为final时,这意味着我们不能更改该实例的值。为此,我们需要在声明或构造函数中初始化最终变量。如果两者都没有完成,则会显示编译时错误。初始化后,如果尝试重新分配值,则会出现编译时错误。使用静态最终变量,其中数据将在类的所有实例之间共享,并且您希望数据只读。如果您想表示属于该类的每个单独实例但一次的某些数据,请使用实例最终变量已存储且无法更改。静态和实例关键字的使用取决于您的设计需求以及该数据在域中表示的内容。如果跨类实例使用数据,则不需要每个对象的单独副本/内存引用。
"Static" keyword makes the variable property of the class rather than individual instances of the class. There will be one copy of that variable that is shared amongst all the instances of that class. Any change in the state of the static variable will be reflected across all the instances. Add final to static and we get a variable that has been initialised once and for all at the class loading time and cannot be changed later by any instance of the class. Static final variables need to be initialised at the declaration time else we have compile time error.
As far as private instance field is concerned, it refers to the property /state of an object /instance of a class. Each instance /object of the class will have its own copy of instance variable. When instance variable is declared final, it means we cannot change its value for this instance. For this we need to initialise the final variable either at declaration or in the constructor.If its not done in either of them, compile time error will show. Once initialised, if you try to reassign a value you will get a compile time error. Use static final variables where the data will be shared across all the instances of the class and you want the data to be read only.Use instance final variable if you want to represent some data that belongs to a each individual instance of the class but once stored cannot be changed. Usage of static and instance key word depends upon your design needs and what that data represents in the domain. If the data is used across the class instances then there is no need for individual copies/memory references for each object.