在Java中,有什么区别:

private final static int NUMBER = 10;

and

private final int NUMBER = 10;

两者都是私有的和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值。

其他回答

根据Jon的回答,如果你使用静态韵母,它将表现为一种“定义”。一旦你编译了使用它的类,它将在编译后的.class文件中被烧毁。 在这里查看我的帖子。

对于你的主要目标:如果你没有在类的不同实例中使用不同的NUMBER,我建议使用final和static。 (您只需要记住,在不考虑像我的案例研究所描述的那样可能出现的问题的情况下,不要复制已编译的类文件。大多数情况下不会发生这种情况,别担心:))

为了向你展示如何在实例中使用不同的值,检查下面的代码:

public class JustFinalAttr {
  public final int Number;

  public JustFinalAttr(int a){
    Number=a;
  }
}

...System.out.println(new JustFinalAttr(4).Number);

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

class Test{
  public final int a;
}

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

因此,每个实例都有不同的字段a值。

对于静态final,所有实例共享相同的值,并且在第一次初始化后不能更改。

class TestStatic{
      public static final int a = 0;
}

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

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

private static final int NUMBER = 10;

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

以下是我的观点:

final           String CENT_1 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS";
final   static  String CENT_2 = new Random().nextInt(2) == 0 ? "HEADS" : "TAILS";

例子:

package test;

public class Test {

    final long OBJECT_ID = new Random().nextLong();
    final static long CLASSS_ID = new Random().nextLong();

    public static void main(String[] args) {
        Test[] test = new Test[5];
        for (int i = 0; i < test.length; i++){
            test[i] = new Test();
            System.out.println("Class id: "+test[i].CLASSS_ID);//<- Always the same value
            System.out.println("Object id: "+test[i].OBJECT_ID);//<- Always different
        }
    }
}

关键是变量和函数可以返回不同的值。因此,最终变量可以被赋予不同的值。

这是另一个简单的例子来理解静态,静态final, final变量的用法。代码注释有适当的解释。

public class City {

    // base price that is always same for all objects[For all cities].
    private static double iphone_base_price = 10000;

    // this is total price = iphone_base_price+iphone_diff;
    private double iphone_citi_price;

    // extra price added to iphone_base_price. It is constant per city. Every
    // city has its own difference defined,
    private final double iphone_diff;

    private String cityName = "";

    // static final will be accessible everywhere within the class but cant be
    // changed once initialized.
    private static final String countryName = "India";

    public City(String cityName, double iphone_diff) {
        super();
        this.iphone_diff = iphone_diff;
        iphone_citi_price = iphone_base_price + iphone_diff;
        this.cityName = cityName;

    }

    /**
     * get phone price
     * 
     * @return
     */
    private double getPrice() {

        return iphone_citi_price;
    }

    /**
     * Get city name
     * 
     * @return
     */
    private String getCityName() {

        return cityName;
    }

    public static void main(String[] args) {

        // 300 is the
        City newyork = new City("Newyork", 300);
        System.out.println(newyork.getPrice() + "  " + newyork.getCityName());

        City california = new City("California", 800);
        System.out.println(california.getPrice() + "  " + california.getCityName());

        // We cant write below statement as a final variable can not be
        // reassigned
        // california.iphone_diff=1000; //************************

        // base price is defined for a class and not per instances.
        // For any number of object creation, static variable's value would be the same
        // for all instances until and unless changed.
        // Also it is accessible anywhere inside a class.
        iphone_base_price = 9000;

        City delhi = new City("delhi", 400);
        System.out.println(delhi.getPrice() + "  " + delhi.getCityName());

        City moscow = new City("delhi", 500);
        System.out.println(moscow.getPrice() + "  " + moscow.getCityName());

        // Here countryName is accessible as it is static but we can not change it as it is final as well. 
        //Something are meant to be accessible with no permission to modify it. 
        //Try un-commenting below statements
        System.out.println(countryName);

        // countryName="INDIA";
        // System.out.println(countryName);

    }

}