String常量池问题

String常量池问题

leetcode682题,判断语句需要比较两个字符串是否相等,在本地编译器上可以通过,结果正确,但是上传leetcode,发现存在报错Integer.valueOf(string),emm。。。想不通就随便把==换成了equals,结果就好了,但是很奇怪的一点是在本地编译器上是可以通过的。
String常量池问题

String常量池问题

最终调试了几次发现是常量池的问题,把前面的newString a b c改成键盘输入的 ==就是false了。

几个例子

示例1:

String s0=“kvill”;

String s1=“kvill”;

String s2=“kv” + “ill”;

System.out.println( s0==s1 );

System.out.println( s0==s2 );

结果为:

true

true
分析:首先,我们要知结果为道Java 会确保一个字符串常量只有一个拷贝。

因为例子中的 s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0= =s1为true;而”kv”和”ill”也都是字符串常量,当一个字 符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中” kvill”的一个引用。所以我们得出s0= =s1= =s2;

示例2:

Java代码

String s0=“kvill”;

String s1=new String(“kvill”);

String s2=“kv” + new String(“ill”);

System.out.println( s0==s1 );

System.out.println( s0==s2 );

System.out.println( s1==s2 );

结果为:

false

false

false

分析:用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。

s0还是常量池 中"kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分 new String(”ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。

总结:
栈中用来存放一些原始数据类型的局部变量数据和对象的引用(String,数组.对象等等)但不存放对象内容

堆中存放使用new关键字创建的对象.

字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆).有的是编译期就已经创建好,存放在字符串常 量池中,而有的是运行时才被创建使用new关键字,存放在堆中。

总之也不用再纠结了,对象用equals ,compareTo 基础类型用 == 大于小于就完事了。