了解 java 个最终变量
Understanding java final variables
你能帮我理解如果在字符串连接中使用最终变量会发生什么吗?
这是一个认证问题,所以不是关于如何比较 string
的问题
String var1 = "varan";
String an = "an";
final String an2 = "an";
System.out.println(var1 == ("var"+an));
System.out.println(var1 == ("var"+an2));
输出:
false
true
TL;DR
因为"var"+an
是在运行时新创建的不同的String
Object
而"var"+an2
是编译时常量实习,并引用 var1
引用的同一地址。
考虑以下与您的代码类似的示例。
public class TestString {
public static void main(String[] args) {
String Whosebug = "Whosebug";
String overflow = "Overflow";
final String overflowFinal = "Overflow";
if (overflow == overflowFinal) {
System.out.println("Both overflows are same!");
}
if (Whosebug == ("stack" + overflow)) {
System.out.println("Stack and overflow have same reference !");
}
if (Whosebug == ("stack" + overflowFinal)) {
System.out.println("Stack and overflowFinal have same reference !");
}
}
}
它将给出以下输出:
Both overflows are same!
Stack and overflowFinal have same reference !
首先请注意,==
比较的是 Strings
的引用,而不是实际值。
JLS 15.18.1 表示,
The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).
所以,从上面的陈述我们可以说 "stack" + overflow
将类似于 String newString = new String("Whosebug");
(在内部 编译器 将使用 StringBuilder
来执行此操作连接)。
对于 final
String
JLS 4.12.4 个州,
A variable of primitive type or type String
, that is final
and initialized with a compile-time constant expression (§15.28), is called a constant variable.
and so §15.28 says
A constant expression is an expression denoting a value of primitive type or a String
that does not complete abruptly and is composed using only the following:
...
- The additive operators
+
and -
...
Compile-time constant expressions of type String
are always "interned" so as to share unique instances, using the method String.intern
.
现在,上面的语句说如果我们将 String
声明为 final
,它最终会变成 常量表达式。
请注意 String
字面量也被保留。
Interned String
表示如果您正在创建具有相同内容的 String
和一个 String
( 由 检查 .equals()
method) 已经存在于内存中,那么它不会创建新的 String
但它会引用 same 内存位置。
例如,
String a = "test";//String literals
String b = "test";
System.out.println("Is a & b interned ? :"+(a == b));
输出:
Is a & b interned ? : true
你能帮我理解如果在字符串连接中使用最终变量会发生什么吗? 这是一个认证问题,所以不是关于如何比较 string
的问题String var1 = "varan";
String an = "an";
final String an2 = "an";
System.out.println(var1 == ("var"+an));
System.out.println(var1 == ("var"+an2));
输出:
false
true
TL;DR
因为"var"+an
是在运行时新创建的不同的String
Object
而"var"+an2
是编译时常量实习,并引用 var1
引用的同一地址。
考虑以下与您的代码类似的示例。
public class TestString {
public static void main(String[] args) {
String Whosebug = "Whosebug";
String overflow = "Overflow";
final String overflowFinal = "Overflow";
if (overflow == overflowFinal) {
System.out.println("Both overflows are same!");
}
if (Whosebug == ("stack" + overflow)) {
System.out.println("Stack and overflow have same reference !");
}
if (Whosebug == ("stack" + overflowFinal)) {
System.out.println("Stack and overflowFinal have same reference !");
}
}
}
它将给出以下输出:
Both overflows are same!
Stack and overflowFinal have same reference !
首先请注意,==
比较的是 Strings
的引用,而不是实际值。
JLS 15.18.1 表示,
The result of string concatenation is a reference to a String object that is the concatenation of the two operand strings. The characters of the left-hand operand precede the characters of the right-hand operand in the newly created string.
The String object is newly created (§12.5) unless the expression is a constant expression (§15.28).
所以,从上面的陈述我们可以说 "stack" + overflow
将类似于 String newString = new String("Whosebug");
(在内部 编译器 将使用 StringBuilder
来执行此操作连接)。
对于 final
String
JLS 4.12.4 个州,
A variable of primitive type or type
String
, that isfinal
and initialized with a compile-time constant expression (§15.28), is called a constant variable.and so §15.28 says
A constant expression is an expression denoting a value of primitive type or a
String
that does not complete abruptly and is composed using only the following:...
- The additive operators
+
and-
...
Compile-time constant expressions of type
String
are always "interned" so as to share unique instances, using the methodString.intern
.
现在,上面的语句说如果我们将 String
声明为 final
,它最终会变成 常量表达式。
请注意 String
字面量也被保留。
Interned String
表示如果您正在创建具有相同内容的 String
和一个 String
( 由 检查 .equals()
method) 已经存在于内存中,那么它不会创建新的 String
但它会引用 same 内存位置。
例如,
String a = "test";//String literals
String b = "test";
System.out.println("Is a & b interned ? :"+(a == b));
输出:
Is a & b interned ? : true