因为"ab"和"cd"都是固定的值了,所以"ab"+"cd"也是固定的,它的值在编译时期就会被确定,是存在于栈内存中的字符池中,所以 String e ="ab"+"cd";中e就会在栈中找到"abcd",所以String c ="abcd";中的c和e是相等的。a+b中的a和b在运算出d的值之前,都没有被赋值,他们何时被赋值,以及被赋予什么样的值,JVM是不知道的,相当于都是个变数,因此a和b在被赋值之前,性质类似于一个变量。那么d就不能在编译期被确定,而只能在运行时被创建了,所以+号的作用是返回另外一个新建的String对象,而不是在栈中找string这个值,所以是在堆中存在的。所以String d =a+b;中的d是一个新new的对象,那么d的地址和c的地址自然不是同一个,所以为false。a+"cd"虽然有一个变量,但结果仍是不确定的,和a+b差不多,都是要在堆里新建一个对象返回的。
javac编译可以对字符串常量直接相加的表达式进行优化,不必要等到运行期去进行加法运算处理,
而是在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果。所以
String d =a+b;是在堆里重新创建了一个新的对象abcd;其他几个和这个道理一样,都有新的对象创建,所以为false
再看String e ="ab"+"cd";在编译时去掉其中的加号,直接将其编译成一个这些常量相连的结果abcd,所以“==”的结果是true
String h =new String("abcd"); 这里用到new关键字,所以创建了一个新的abde所以“==”也为false 作者: 王一军 时间: 2012-6-30 22:45
你看下吧,我在下边加了必要的注释,相信你会看懂的
public class StringDemo {
public static void main(String[] args){
String a ="ab";
String b ="cd";
String c ="abcd";
String d =a+b;
String e ="ab"+"cd";
String f =a+"cd";
String g ="ab"+b;
String h =new String("abcd");
System.out.println(c==d);//false//这个为什么会等于false呢?那我们首先来看下c这个对象String c ="abcd";是将内存中“abcd”的地址付给了C而我们再来看看D String d =a+b;d是将a和b连个对象加起来创建了新的对象并把新对象地址给了d这个时候c和d里边的值谁然都是“abcd”但是,d是一个新的对象而c确不是,这个时候你用==比较他们的内存地址,既然对象都不是一个,那内存地址肯定不一样了所以是false。
System.out.println(c==e);//true//这个看似和上边是一样的为什么结果会不一样呢?其实你自己洗看看 String c ="abcd";这个是c String e ="ab"+"cd";这个是e 在java中String类型如果使用+号的话,就等于是一个连接作用,起到吧 “ab”和“cd”两个字符串连接起来,而在编译器编译的时候会把+去掉,编译完以后就会成String e ="abcd";这样的会和c就一样了他们都是把“abcd”的内存地址取了出来,所以你用==号的时候,内存地址一致,所以输出 了true
下边这些false的原因基本上和第一个是一样的,你只要仔细看看就会明白了