public static final String Test = "ABC";
public static String Test = "ABC";
请展示Java中"final static String"和"static String"之间的差异。 除了final不能改变之外,还有哪些区别?谢谢。 在更复杂的情况下,例如多线程和继承,是否有所改变?
public static final String Test = "ABC";
public static String Test = "ABC";
static int intVal = 42;
static String strVal = "Hello, world!";
static final int intVal = 42;
static final String strVal = "Hello, world!";
因为常量进入dex文件中的静态字段初始化程序,所以该类不再需要方法。引用intVal的代码将直接使用整数值42,而对strVal的访问将使用相对廉价的“字符串常量”指令而不是字段查找。
注意:
此优化仅适用于基本类型和String常量,而不适用于任意引用类型。尽管如此,尽可能声明常量为static final仍是一个好习惯。
希望这能解决您的疑虑。
更多细节请参见UseFinal
当涉及到变量时
final Static String
- 常量,是类变量static String
- 类变量,不是常量static final String s1;
static String s2;
第一行无法编译,第二行可以编译。
对于基本类型还有更多内容。
final int x = 1;
void x() {
int y = x + 1;
}
字节码
ICONST_2
ISTORE 1
这句话的意思是int y = 2
,因为x是一个常量(虽然它不是静态的)
如果我们改变
int x = 1;
字节码
ALOAD 0
GETFIELD Test1.x : I
ICONST_1
IADD
ISTORE 1
JVM读取x并计算y
String
最初就是不可变的,因此在这种情况下,这个区别是无关紧要的,它只是一个无法以任何方式修改的变量。你自己说了:最后一个不能被分配。据我所知,final
修饰符除此之外没有其他行为。我唯一能想到的是,由于Test
是public
、static
和final
的,编译器将自动替换代码中所有出现的Test
并用字符串字面量"ABC"
替换它,尽管由于字符串将被内部化,它不会对代码产生任何影响。基本上,final只是防止字符串被分配给不同的引用。
final
类不能被子类化。这就像C#中的sealed
类。
final
方法不能被覆盖。
final
字段只能被初始化/赋值一次,就像常量一样,但不一定在编译时就已知。
static
成员在类的所有实例之间共享。
因此,static final
通常用于永远不再更改的内容,但不一定是在编译时硬编码的。
在声明Java变量为static final时,编译后的Java类会产生更快的性能。
您无法像下面这样更改final的引用
public static final String Test1 = "ABC";
public static String Test2 = "ABC";
public static void testFinal()
{
Test2 = Test1; //ok
Test1 = Test2; //fail
}
声明为final的字符串不能被重新赋值。该字符串作为常量使用。
声明为static的字符串可以在不需要对象或类名的情况下调用。
静态变量不维护封装性。将静态变量声明为final后,任何对象都无法更改其值,但可以访问它。
public class Demo {
static final String str = "Hello";
public static void main(String args[]) {
// str = "world"; // 报错
System.out.println(str); // 不需要对象就能调用
System.out.println(Demo.str);// 使用类名调用
}
}
Demo d1 = new Demo();
d1.str = "World";
实时例子
静态常量字符串 truth = "太阳从东方升起";
这里是:
1)final static String
:当你使用final时,它是一个常量,你不能在整个程序中改变它的值。它不是一个变量,你不能改变它的值。在Java中,我们使用final关键字来声明常量。在声明常量时,我们应该遵循所有大写字母和下划线来分隔单词。例如:MAX_INPUT_TIME、CONNECTION_POOL_SIZE、MAX_USER等。
2)static String
:你可以为类的成员变量使用static,但不能为局部变量使用。静态变量是静态的,即使没有创建类的实例也可以访问。因此,你可以通过object.<static_variable_name>
或ClassName.<static_variable_name>
来使用它们。它们对于类的所有实例都是可访问的,并且保持相同的值。
例如:
Class A {
static int counter; // it will be default to 0
}
现在使用这个类:
System.out.println(A.counter); // output: 0
A.counter++;
System.out.println(A.counter); // output: 1
// Declare an instance of class A
A o1 = new A();
o1.counter++;
System.out.println(o1.counter); // output: 1
// Declare another instance of class A
A o2 = new A();
System.out.println(o1.counter); // output: 1
# You still get it one and not 0, if it was non-static you would get it as 0;
final
会产生不同的行为。这与可读性有什么关系? - ApproachingDarknessFish