在Java中,有什么区别:
private final static int NUMBER = 10;
and
private final int NUMBER = 10;
两者都是私有的和final的,不同的是静态属性。
更好的是什么?,为什么?
在Java中,有什么区别:
private final static int NUMBER = 10;
and
private final int NUMBER = 10;
两者都是私有的和final的,不同的是静态属性。
更好的是什么?,为什么?
当前回答
对于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:一旦Final变量被赋值,它总是包含相同的值。 无论变量是否是静态的 static:对于内存中一次初始化的所有实例,它将只有一个变量
以下是我的观点:
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
}
}
}
关键是变量和函数可以返回不同的值。因此,最终变量可以被赋予不同的值。
读了答案后,我发现没有真正的测试能真正抓住重点。以下是我的观点:
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,变量的值将在你所有的实例中是相同的,如果在一个实例中改变了,其他实例也会改变。