Java 中的 final 变量是否需要使用 "static" 关键字?
Is there any need to use "static" keyword for final variables in Java?
我对Java中的final
和static
关键字感到困惑,需要澄清以下问题:
1.变量有没有必要用static
?例如:
public final int ERROR_CODE = 200;
我觉得没必要用static
如下图。我错了吗?
public static final int ERROR_CODE = 200;
2. 据我所知,静态对于方法是有意义的,类 可以在不创建实例的情况下使用它们。 BUT,同样在这个静态方法中使用一个static
变量,同时改变它们的值也是有意义的:
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
3. 我可以更改 final 和 static 关键字的顺序,例如
public static final int ERROR_CODE = 200;
或
public final static int ERROR_CODE = 200;
static
和final
是不同的概念。 static
成员属于 class 而不是实例,而您不能重新分配 final
变量。
MyClass.myVariable = 5; //This change is reflected in both instances
➡️ 如果 myVariable
被声明 final
就不可能了。
Can I change the order of final and static keywords e.g.
public static final int ERROR_CODE = 200; or
public final static int ERROR_CODE = 200;
➡️是的。这没有任何区别。
#1 用文字初始化一个非静态最终变量:
class MyClass {
public final int ERROR_CODE = 200;
}
一个坏习惯,因为:
- class 的每个实例都会有一个具有相同值的此变量的副本,因为它打算用作全局常量,这是一种内存浪费。
- 静态访问常量是不可能的,所以
MyClass.ERROR_CODE
不会编译,如果你只需要这个值,你总是需要一个实例,例如new MyClass().ERROR_CODE
#2 静态变量
静态变量在某些情况下很有用,例如单例模式或 class 相关的缓存,或者当你想在相同 class
的所有实例之间共享一些公共数据时
#3 是
也许您的 class 还没有做到这一点,但是 class 是一个对象,由 classloader 管理。 classloader 加载 class 并确保只有一个 class 对象。 class 对象是静态变量和方法所在的地方。
对于#1,静态意味着有一个变量属于class。没有 static 的声明意味着它是一个实例变量,并且您为 class 创建的每个实例都有自己的变量。对于常量,将您的变量设置为 static final,这样就只有一个。
Final 表示值不变。如果变量是原始变量,则不能重新分配值。如果变量是引用类型,则不能更改变量指向的内容。如果指向的对象本身是可变的,则 final 不会更改它。
对于2,静态变量属于class,你的一个静态方法可以改变变量中的内容,其他方法可以看到变化。全局可变状态令人困惑,而且您正在将 OO 良好实践抛在脑后,进入肮脏的黑客领域,因此在使用此功能时非常谨慎是个好主意。
#3:来吧,你可以在大约 10 秒内亲自尝试一下。无论哪种方式都有效。 google style guide 建议“static final”。
1:static
不是 需要的 只要常量只能从实例中访问(或使用实例)。但是要在没有实例的情况下访问它,它必须是 static
。更重要的是,恕我直言,它应该是一个 class 变量,因为拥有一个常量(独立于实例)的实例变量是没有意义的 - 另请参见下一点。
2:你所描述的是功能 - 某种相关的数据设计,数据模型,static
表示 class 成员(字段,方法)与实例对比成员 - OO 设计的重要组成部分
3:顺序不重要...但是,Java Language Specification 建议:
MethodModifier:
(one of)
Annotation public protected private
abstract static final synchronized native strictfp
...
If two or more (distinct) method modifiers appear in a method declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for MethodModifier.
我对Java中的final
和static
关键字感到困惑,需要澄清以下问题:
1.变量有没有必要用static
?例如:
public final int ERROR_CODE = 200;
我觉得没必要用static
如下图。我错了吗?
public static final int ERROR_CODE = 200;
2. 据我所知,静态对于方法是有意义的,类 可以在不创建实例的情况下使用它们。 BUT,同样在这个静态方法中使用一个static
变量,同时改变它们的值也是有意义的:
public class MyClass {
public static int myVariable = 0;
}
//Now in some other code creating two instances of MyClass
//and altering the variable will affect all instances
MyClass instance1 = new MyClass();
MyClass instance2 = new MyClass();
MyClass.myVariable = 5; //This change is reflected in both instances
3. 我可以更改 final 和 static 关键字的顺序,例如
public static final int ERROR_CODE = 200;
或
public final static int ERROR_CODE = 200;
static
和final
是不同的概念。 static
成员属于 class 而不是实例,而您不能重新分配 final
变量。
MyClass.myVariable = 5; //This change is reflected in both instances
➡️ 如果 myVariable
被声明 final
就不可能了。
Can I change the order of final and static keywords e.g.
public static final int ERROR_CODE = 200; or
public final static int ERROR_CODE = 200;
➡️是的。这没有任何区别。
#1 用文字初始化一个非静态最终变量:
class MyClass {
public final int ERROR_CODE = 200;
}
一个坏习惯,因为:
- class 的每个实例都会有一个具有相同值的此变量的副本,因为它打算用作全局常量,这是一种内存浪费。
- 静态访问常量是不可能的,所以
MyClass.ERROR_CODE
不会编译,如果你只需要这个值,你总是需要一个实例,例如new MyClass().ERROR_CODE
#2 静态变量
静态变量在某些情况下很有用,例如单例模式或 class 相关的缓存,或者当你想在相同 class
的所有实例之间共享一些公共数据时#3 是
也许您的 class 还没有做到这一点,但是 class 是一个对象,由 classloader 管理。 classloader 加载 class 并确保只有一个 class 对象。 class 对象是静态变量和方法所在的地方。
对于#1,静态意味着有一个变量属于class。没有 static 的声明意味着它是一个实例变量,并且您为 class 创建的每个实例都有自己的变量。对于常量,将您的变量设置为 static final,这样就只有一个。
Final 表示值不变。如果变量是原始变量,则不能重新分配值。如果变量是引用类型,则不能更改变量指向的内容。如果指向的对象本身是可变的,则 final 不会更改它。
对于2,静态变量属于class,你的一个静态方法可以改变变量中的内容,其他方法可以看到变化。全局可变状态令人困惑,而且您正在将 OO 良好实践抛在脑后,进入肮脏的黑客领域,因此在使用此功能时非常谨慎是个好主意。
#3:来吧,你可以在大约 10 秒内亲自尝试一下。无论哪种方式都有效。 google style guide 建议“static final”。
1:static
不是 需要的 只要常量只能从实例中访问(或使用实例)。但是要在没有实例的情况下访问它,它必须是 static
。更重要的是,恕我直言,它应该是一个 class 变量,因为拥有一个常量(独立于实例)的实例变量是没有意义的 - 另请参见下一点。
2:你所描述的是功能 - 某种相关的数据设计,数据模型,static
表示 class 成员(字段,方法)与实例对比成员 - OO 设计的重要组成部分
3:顺序不重要...但是,Java Language Specification 建议:
MethodModifier: (one of) Annotation public protected private abstract static final synchronized native strictfp
...
If two or more (distinct) method modifiers appear in a method declaration, it is customary, though not required, that they appear in the order consistent with that shown above in the production for MethodModifier.