前者是在编译时求值,在编译成class文件之前,编译器已经知道ab的内容是“abc”了,编译器看到a的内容也是一模一样的“abc”,于是就做了个优化,让a和ab引用同一个字符串对象,这样,空间就节省了。后者是在运行时执行完String ab= b+"c";之后,才发现ab的内容是“abc”,如果你说的是真的,那就说明java虚拟机不会像java编译器一样做这种优化。
调试欢乐多
String ab= (b+"c").intern();
public String intern()
Returns a canonical representation for the string object.
A pool of strings, initially empty, is maintained privately by the class String. When the intern method is invoked, if the pool already contains a string equal to this String object as determined by the equals(Object) method, then the string from the pool is returned. Otherwise, this String object is added to the pool and a reference to this String object is returned. It follows that for any two strings s and t, s.intern() == t.intern() is true if and only if s.equals(t) is true. All literal strings and string-valued constant expressions are interned. String literals are defined in §3.10.5 of the Java Language Specification
Returns:
a string that has the same contents as this string, but is guaranteed to be from a pool of unique strings.
1 如果另一个常量池入口(constant pool entry)被标记为constant-string,并指出同样的unicode字符已经被解析了。那么该项操作的结果就是为之前的常量驰入口创建string实例的引用
2否则的话 ,如果intern()方法已经被这个常量描叙的一个同样的unicode字符序列的string实例已被调用过了,这个string实例就是该项操作的结果;
3 一个新的string实例被创建的话,它包含了constant—string入口的描叙的unicode字符序列,这个string实例就是该项操作的结果。
String a = new String("abc")
String b = new String("abc");
a=b的结果还是false;
其他的就像楼上几位大侠说得了,String ab= "ab"+"c";,编译器执行到这里的时候会查找常量池,如果能找到"abc",那么就将String ab指向这个"abc",意味着此时"abc"有两个引用,ab和a。
而String ab=b+"c",编译的时候并不知道b是什么(java的后期绑定策略)。
有个疑问,此时的ab指向什么?
java在编译期并不知道ab是什么,只知道是b+"c",b是个String,保证没有出现语法错误。
在运行期,才知道b="ab",并运行b+"c",构建新的string "abc",并建立一个引用String ab指向这个新的String。
这样,两次建立的String指向了不同的引用,所以==为false。
String a = "abc";
String b = "ab";
String ab= "ab"+"c";
System.out.println(a==ab);//true String a = "abc";
String b = "ab";
String ab= b+"c";
System.out.println(a==ab);//false为什么两个结果不同?
原因:
此题无关乎String or StringBuffered
此题的原因是在String class中=符号是一个运算符重载,而返回的是一个常量,换句话说
String a = "abc" a 指向的是一个常量
在此题中 String a = "abc"; JDK编译器将会首先生成一个static final常量,然后将地址赋予变量a
而之后 String ab= "ab"+"c"; 编译器发现依然是一个"abc"的字符串常量,于是又将之前生成的字符串常量地址赋予变量ab
ab == a比较的是两个String Object所引用的地址,他们属于同一个地址,所以得答案True之后一种做法
String ab= b+"c";
由于之后产生了一个b实体变量参与运算,导致编译器会再分配一个地址给ab,就相当与new String(),所以当使用ab == a时,引用不同的地址得到的答案是false。这题的关键是如果使用默认的String class 中的 ==运算符号他们将进行地址比较,而非内容比较。
@.@||~
int c = 1+2.
编译的时候jvm已经知道c的值是3了?
所以
public static final int SECONDS_IN_ONE_DAY = 86400;
还不如:
public static final int SECONDS_IN_ONE_DAY = 24 * 60 * 60;
后者可读性更好,而生成的结果是一样的。
既然ab="ab"+"c"在编译时获得了一个地址,ab=b+"c"在运行时是如何用intern把自己的地址修改为和"ab"+"c"一致的。
对zyyhero2001(风之传说)贴的步骤 不是很明白
其实zyyhero2001兄说得有些不正确,在这里其实是因为"ab"+"c" is a final static entity,而b + "c" is only a entity, not final static。
具体步骤参照第11层楼
@.@||~