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)
两者都是private
和final
,不同之处在于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)
如果它不能改变,那么每个实例只有一个副本是没有意义的.
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)
Mar*_*aux 30
甲static
变量保持在应用程序的整个生命周期的存储器,和类加载期间被初始化.static
每次构造new
对象时都会初始化非变量.通常最好使用:
private static final int NUMBER = 10;
Run Code Online (Sandbox Code Playgroud)
为什么?这减少了每个实例的内存占用量.它可能也有利于缓存命中.它只是有意义:static
应该用于在某种类型(aka class
)的所有实例(aka对象)之间共享的东西.
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变量提供相同的地址.
虽然其他答案似乎很清楚,通常没有理由使用非静态常量,但我找不到任何人指出可能在其常量变量上有不同值的各种实例.
请考虑以下示例:
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实例现在将打印三个不同的随机值,因为每个实例都有自己的随机生成的常量值.
我想不出任何情况,在不同的实例上有不同的常量值是非常有用的,但我希望这有助于指出静态和非静态终结之间存在明显的区别.