私有最终静态属性与私有最终属性

本文翻译自:private final static attribute vs private final attribute

In Java, what's the difference between: 在Java中,两者之间有什么区别?

private final static int NUMBER = 10;

and

private final int NUMBER = 10;

Both are private and final , the difference is the static attribute. 两者都是privatefinal ,不同之处在于static属性。

What's better? 有什么更好的? And why? 又为什么呢?


#1楼

参考:https://stackoom.com/question/5WlZ/私有最终静态属性与私有最终属性


#2楼

For final , it can be assigned different values at runtime when initialized. 对于final ,可以在初始化时在运行时为其分配不同的值。 For example 例如

Class Test{
  public final int a;
}

Test t1  = new Test();
t1.a = 10;
Test t2  = new Test();
t2.a = 20; //fixed

Thus each instance has different value of field a . 因此,每个实例具有字段a的不同值。

For static final , all instances share the same value, and can't be altered after first initialized. 对于static final ,所有实例共享相同的值,并且在首次初始化后不能更改。

Class TestStatic{
      public static final int a;
}

TestStatic t1  = new TestStatic();
t1.a = 10;
TestStatic t2  = new TestStatic();
t1.a = 20;   // ERROR, CAN'T BE ALTERED AFTER THE FIRST INITIALIZATION.

#3楼

Reading the answers I found no real test really getting to the point. 阅读答案,我发现没有真正的考验真的很关键。 Here are my 2 cents : 这是我的2美分:

public class ConstTest
{

    private final int         value             = 10;
    private static final int  valueStatic       = 20;
    private final File        valueObject       = new File("");
    private static final File valueObjectStatic = new File("");

    public void printAddresses() {


        System.out.println("final int address " +
                ObjectUtils.identityToString(value));
        System.out.println("final static int address " +
                ObjectUtils.identityToString(valueStatic));
        System.out.println("final file address " + 
                ObjectUtils.identityToString(valueObject));
        System.out.println("final static file address " + 
                ObjectUtils.identityToString(valueObjectStatic));
    }


    public static void main(final String args[]) {


        final ConstTest firstObj = new ConstTest();
        final ConstTest sndObj = new ConstTest();

        firstObj.printAdresses();
        sndObj.printAdresses();
    }

}

Results for first object : 第一个对象的结果:

final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@6c22c95b
final static file address java.io.File@5fd1acd3

Results for 2nd object : 第二个对象的结果:

final int address java.lang.Integer@6d9efb05
final static int address java.lang.Integer@60723d7c
final file address java.io.File@3ea981ca
final static file address java.io.File@5fd1acd3

Conclusion : 结论:

As I thought java makes a difference between primitive and other types. 正如我认为Java在原始类型和其他类型之间有所不同。 Primitive types in Java are always "cached", same for strings literals (not new String objects), so no difference between static and non-static members. Java中的原始类型总是“缓存”的,与字符串文字(不是新的String对象)相同,因此静态成员和非静态成员之间没有区别。

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. 将valueStatic的值更改为10甚至会更进一步,因为Java将为两个int变量赋予相同的地址。


#4楼

A static variable stays in the memory for the entire lifetime of the application, and is initialised during class loading. static变量在应用程序的整个生命周期中都保留在内存中,并在类加载期间初始化。 A non- static variable is being initialised each time you construct a new object. 每次构造new对象时,都会初始化一个非static变量。 It's generally better to use: 通常最好使用:

private static final int NUMBER = 10;

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 (aka objects) of a certain type (aka class ). 这很有意义:应该将static用于在某种类型(aka class )的所有实例(aka对象)之间共享的事物。


#5楼

In general, static means "associated with the type itself, rather than an instance of the type." 通常, static是指“与类型本身相关联,而不是与类型实例相关联”。

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: 因此,例如:

Test x = new Test();
Test y = new Test();
x.instanceVariable = 10;
y.instanceVariable = 20;
System.out.println(x.instanceVariable);

prints out 10: y.instanceVariable and x.instanceVariable are separate, because x and y refer to different objects. 打印出10: y.instanceVariablex.instanceVariable是分开的,因为xy引用不同的对象。

You can refer to static members via references, although it's a bad idea to do so. 可以通过引用引用静态成员,尽管这样做不是一个好主意。 If we did: 如果我们这样做:

Test x = new Test();
Test y = new Test();
x.staticVariable = 10;
y.staticVariable = 20;
System.out.println(x.staticVariable);

then that would print out 20 - there's only one variable, not one per instance. 那么将输出20-只有一个变量,每个实例都没有。 It would have been clearer to write this as: 将其写为:

Test x = new Test();
Test y = new Test();
Test.staticVariable = 10;
Test.staticVariable = 20;
System.out.println(Test.staticVariable);

That makes the behaviour much more obvious. 这使行为更加明显。 Modern IDEs will usually suggest changing the second listing into the third. 现代IDE通常会建议将第二个列表更改为第三个列表。

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). 不需要像下面这样的内联声明来初始化该值,因为每个实例将具有其自己的NUMBER但始终具有相同的值(是不可变的,并使用文字进行了初始化)。 This is the same than to have only one final static variable for all instances. 这与在所有实例中只有一个final static变量相同。

private final int NUMBER = 10;

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: 但是,如果在像这样的构造函数中初始化是有意义的:

// No initialization when is declared
private final int number;

public MyClass(int n) {
   // The variable can be assigned in the constructor, but then
   // not modified later.
   number = n;
}

Now, for each instance of MyClass , we can have a different but immutable value of number . 现在,对于MyClass每个实例,我们可以拥有一个不同但不变的number值。


#6楼

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. 没有它,该变量可以在其实例存在时被gc'd。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值