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

286 java static attributes final private

在Java中,有什么区别:

private final static int NUMBER = 10;
Run Code Online (Sandbox Code Playgroud)

private final int NUMBER = 10;
Run Code Online (Sandbox Code Playgroud)

两者都是privatefinal,不同之处在于static属性.

什么更好?为什么?

Jon*_*eet 298

通常,static表示"与类型本身相关联,而不是类型的实例 ".

这意味着您可以引用静态变量而无需创建该类型的实例,并且引用该变量的任何代码都指的是完全相同的数据.将其与实例变量进行比较:在这种情况下,每个类的实例都有一个独立的变量版本.例如:

Test x = new Test();
Test y = new Test();
x.instanceVariable = 10;
y.instanceVariable = 20;
System.out.println(x.instanceVariable);
Run Code Online (Sandbox Code Playgroud)

打印10:y.instanceVariable并且x.instanceVariable是分开的,因为x并且y引用不同的对象.

可以通过引用引用静态成员,但这样做是个坏主意.如果我们这样做:

Test x = new Test();
Test y = new Test();
x.staticVariable = 10;
y.staticVariable = 20;
System.out.println(x.staticVariable);
Run Code Online (Sandbox Code Playgroud)

然后打印出20 - 只有一个变量,而不是每个实例一个变量.把它写成以下内容会更清楚:

Test x = new Test();
Test y = new Test();
Test.staticVariable = 10;
Test.staticVariable = 20;
System.out.println(Test.staticVariable);
Run Code Online (Sandbox Code Playgroud)

这使得行为更加明显.现代IDE通常会建议将第二个列表更改为第三个.

没有理由有这样的声明

private final int NUMBER = 10;
Run Code Online (Sandbox Code Playgroud)

如果它不能改变,那么每个实例只有一个副本是没有意义的.

  • @Vineet:静态韵母仍然是声明原始常量的方法,除非你有一个枚举数量=) (20认同)
  • 在Java 5中提供枚举之前,静态final是声明常量的常用方法. (9认同)

luc*_*cas 39

对于final,初始化时可以在运行时为其分配不同的值.例如

Class Test{
  public final int a;
}

Test t1  = new Test();
t1.a = 10;
Test t2  = new Test();
t2.a = 20; //fixed
Run Code Online (Sandbox Code Playgroud)

因此,每个实例具有不同的字段a值.

对于静态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.
Run Code Online (Sandbox Code Playgroud)

  • 这不会编译!最终变量必须赋值,或者在其构造函数中赋值.如果给出2个构造函数,则这个答案是正确的,每个构造函数将'a'分配给不同的值. (86认同)
  • 确认,这不会编译.如上所述,必须在构造函数完成之前实例化最终实例变量,并且必须在创建类之前实例化最终的类变量(可以使用静态块).为什么会有这么多的赞成? (14认同)
  • 请删除此答案 (4认同)

Mar*_*aux 30

static变量保持在应用程序的整个生命周期的存储器,和类加载期间被初始化.static每次构造new对象时都会初始化非变量.通常最好使用:

private static final int NUMBER = 10;
Run Code Online (Sandbox Code Playgroud)

为什么?这减少了每个实例的内存占用量.它可能也有利于缓存命中.它只是有意义:static应该用于在某种类型(aka class)的所有实例(aka对象)之间共享的东西.

  • 通过Java编码约定,静态最终变量的名称应全部为大写. (13认同)

duf*_*ymo 16

static表示"与班级相关"; 没有它,变量与类的每个实例相关联.如果它是静态的,那意味着你只有一个在内存中; 如果没有,您将为您创建的每个实例分配一个.static表示只要加载类,变量就会保留在内存中; 没有它,变量的实例可以是gc'd.


Sta*_*ola 12

阅读答案我发现没有真正的测试真正达到目的.这是我的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();
    }

}
Run Code Online (Sandbox Code Playgroud)

第一个对象的结果:

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
Run Code Online (Sandbox Code Playgroud)

第二个对象的结果:

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
Run Code Online (Sandbox Code Playgroud)

结论:

我认为java会在原始类型和其他类型之间产生差异.Java中的原始类型总是"缓存",对于字符串文字(不是新的String对象)也是如此,因此静态和非静态成员之间没有区别.

但是,如果非静态成员不是基本类型的实例,则存在重复内存.

将valueStatic的值更改为10甚至会更进一步,因为Java将为两个int变量提供相同的地址.

  • 'int' - > Integer的自动装箱在这里造成了混乱.您会看到某些(小)int值的自动装箱会导致相同的Integer对象. (2认同)

Mic*_*iel 9

虽然其他答案似乎很清楚,通常没有理由使用非静态常量,但我找不到任何人指出可能在其常量变量上有不同值的各种实例.

请考虑以下示例:

public class TestClass {
    private final static double NUMBER = Math.random();

    public TestClass () {
        System.out.println(NUMBER);
    }
}
Run Code Online (Sandbox Code Playgroud)

创建三个TestClass实例将打印相同的随机值三次,因为只生成一个值并将其存储到静态常量中.

但是,在尝试以下示例时:

public class TestClass {
    private final double NUMBER = Math.random();

    public TestClass () {
        System.out.println(NUMBER);
    }
}
Run Code Online (Sandbox Code Playgroud)

创建三个TestClass实例现在将打印三个不同的随机值,因为每个实例都有自己的随机生成的常量值.

我想不出任何情况,在不同的实例上有不同的常量值是非常有用的,但我希望这有助于指出静态和非静态终结之间存在明显的区别.