理解java最终变量

时间:2015-12-22 14:34:54

标签: java string final

请您帮助我理解如果在字符串连接中使用最终变量会发生什么?    这是一个认证问题,所以不是关于如何比较字符串

的问题
String var1 = "varan";       
String an = "an";
final String an2 = "an";
System.out.println(var1 == ("var"+an));       
System.out.println(var1 == ("var"+an2));

输出:

false
true

1 个答案:

答案 0 :(得分:2)

TL; DR

因为"var"+an是在运行时期间新创建的String Object,而"var"+an2是编译时间常量,并且是参考var1引用的地址相同。

请考虑以下与您的代码类似的示例。

public class TestString {

    public static void main(String[] args) {
        String stackOverflow = "stackOverflow";
        String overflow = "Overflow";

        final String overflowFinal = "Overflow";

        if (overflow == overflowFinal) {
            System.out.println("Both overflows are same!");
        }

        if (stackOverflow == ("stack" + overflow)) {
            System.out.println("Stack and overflow have same reference !");
        }

        if (stackOverflow == ("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表示,

  

字符串连接的结果是对String对象的引用,该对象是两个操作数字符串的串联。左侧操作数的字符位于创建的字符串中右侧操作数的字符之前。

     

String 对象创建的(§12.5),除非表达式是常量表达式(§15.28)。

因此,从上述语句中我们可以说"stack" + overflowString newString = new String("stackOverflow");类似(内部编译器将使用StringBuilder来执行此连接)。

对于final String JLS 4.12.4个州,

  

基本类型或类型String的变量,即final,并使用编译时常量表达式初始化 (§15.28) ,被称为常数变量。

     

所以 §15.28

     

常量表达式是表示基本类型的值的表达式或不突然完成的String的表达式,仅使用以下内容组成:

     

...

     
      
  • 添加剂运算符+-
  •   
     

...

     

类型为String的编译时常量表达式始终为“实习”,以便使用String.intern方法共享唯一实例。

现在,上面的陈述说如果我们将String声明为final,它最终会成为常量表达式

请注意String文字也是实习。

实习String表示您创建的StringString具有相同的内容(通过 .equals() 方法检查)已经存在于内存中,然后它不会创建新的String,但会引用相同的内存位置。

例如,

String a = "test";//String literals
String b = "test";
System.out.println("Is a & b interned ? :"+(a == b));

输出

Is a & b interned ? : true