在Java中,有什么区别:

private final static int NUMBER = 10;

and

private final int NUMBER = 10;

两者都是私有的和final的,不同的是静态属性。

更好的是什么?,为什么?


当前回答

读了答案后,我发现没有真正的测试能真正抓住重点。以下是我的观点:

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();
    }

}

第一个对象的结果:

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

第二个对象的结果:

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

结论:

正如我认为java使原始类型和其他类型之间的区别。Java中的基本类型总是“缓存”的,对于字符串字面量也是如此(不是新的String对象),所以静态和非静态成员没有区别。

然而,如果非静态成员不是基元类型的实例,则存在内存复制。

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

其他回答

"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.

静态变量在应用程序的整个生命周期中都保留在内存中,并在类加载期间初始化。每次构造一个新对象时,都会初始化一个非静态变量。通常更好的方法是:

private static final int NUMBER = 10;

为什么?这减少了每个实例的内存占用。它可能也有利于缓存命中。这是有意义的:静态应该用于在特定类型(类)的所有实例(也就是对象)之间共享的东西。

假设类永远不会有多个实例,那么哪个实例占用更多内存:

私有静态最终int ID = 250; 或 private final int ID = 250;

我已经理解,静态将引用类类型,在内存中只有一个副本,而非静态将在每个实例变量的新内存位置。但是在内部,如果我们只是比较同一个类的1个实例(即不会创建多个实例),那么在1个静态final变量所使用的空间方面是否有任何开销?

由于类中的变量在同一个命令中声明为final和初始化, 绝对没有理由不将其声明为静态,因为无论实例如何,它都具有相同的值。因此,所有实例都可以为一个值共享相同的内存地址,这样就不需要为每个实例创建一个新变量,并通过共享一个公共地址来节省内存,从而节省了处理时间。

通常,静态意味着“与类型本身相关联,而不是与类型的实例相关联”。

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

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

y. instancvariable和x. instancvariable是分开的,因为x和y指向不同的对象。

您可以通过引用引用静态成员,尽管这样做不是一个好主意。如果我们这样做:

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

然后输出20个变量——只有一个变量,而不是每个实例一个变量。这样写会更清楚:

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

这使得这种行为更加明显。现代ide通常建议将第二个清单改为第三个清单。

没有理由像下面这样使用内联声明初始化值,因为每个实例都有自己的NUMBER,但总是具有相同的值(不可变并使用文字初始化)。这与所有实例只有一个最终静态变量是一样的。

private final int NUMBER = 10;

因此,如果它不能更改,就没有必要为每个实例提供一个副本。

但是,如果在这样的构造函数中初始化是有意义的:

// 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;
}

现在,对于MyClass的每个实例,我们可以有一个不同但不可变的number值。