本帖最后由 l493062120 于 2016-4-7 19:05 编辑
1.
- String s1 = "abc";
- String s2 = "abc";
- System.out.println(s1==s2); //true
- System.out.println(s1.equals(s2)); //true
复制代码
解释:
String s1 = "abc"; 在常量池中创建了一个对象 "abc" ,s1指向"abc"。
String s2 = "abc"; 因为常量池中存在"abc"对象,引用s2直接指向常量池中的"abc",没有创建对象,s2与s1指向同一个对象。
“==”比较的是引用是否指向同一个对象。
所以s1 == s2 返回true。
Object中的equals方法 与 == 作用一样,但是字符串类重写了此方法,比较的是对象中的串是否相同。
所以只要是对象中的串相同 equals方法返回的都是true。
2.
- String s1 = "abc";
- String s2 = new String("abc");
- System.out.println(s1==s2); //false
- System.out.println(s1.equals(s2)); //true
复制代码
解释:
String s1 = "abc"; 在常量池中创建了一个对象 "abc" ,s1指向"abc"。
String s2 = new String("abc");在堆中开辟空间创建String对象,s2指向堆中的对象,s1 和 s2 指向的不是同一个对象。
所以s1 == s2 返回false。
equals方法参考1
3.- String s1 = new String("abc");
- String s2 = new String("abc");
- System.out.println(s1==s2); //false
- System.out.println(s1.equals(s2)); //true
复制代码
解释:
String s1 = new String("abc");在堆中开辟空间创建String对象,s1指向堆中的对象。(也在常量池中创建了一个对象 "abc"作为参数传递,所以这个操作创建了两个对象)。
String s2 = new String("abc");在堆中开辟空间又创建一个String对象,s2指向堆中新创建的对象,s1 和 s2 指向的不是同一个对象。(参数"abc"已经在常量池中存在,所以没有创建)。
所以s1 == s2 返回false。
equals方法参考1
4.
- String s1 = "ab" + "c";
- String s2 = "abc";
- System.out.println(s1==s2); //true
- System.out.println(s1.equals(s2)); //true
复制代码
解释:
String s1 = "ab" + "c"; java 中有常量优化机制。"ab" 为字符串常量,"c"为字符串常量。字符串常量与字符串常量连接 在编译期自动优化为"abc",只在常量池中创建了一个"abc"对象,s1指向"abc";
String s2 = "abc"; 因为常量池中存在"abc"对象,引用s2直接指向常量池中的"abc",没有创建对象,s2与s1指向同一个对象。
所以 s1 == s2 返回true。
equals方法参考1
5.
- String s1 = "ab";
- String s2 = s1 + "c";
- String s3 = "abc";
- System.out.println(s2==s3); //false
- System.out.println(s2.equals(s3)); //true
复制代码
解释
String s1 = "ab"; 在常量池中创建了一个对象 "ab" ,s1指向"ab"。
String s2 = s1 + "c";变量连接常量,在堆中创建StringBuilder对象,append(str), 在常量池中创建"c"对象,append("c"),最后调用toString方法在堆中创建String对象,s2指向该String对象。
String s3 = "abc"; 在常量池中创建了一个对象 "abc" ,s3指向"abc"。
所以 s2 == s3 返回false
equals方法参考1
6
- String s1 = new String("ab");
- String s2 = s1 + "c";
- String s3 = "abc";
- System.out.println(s2==s3); //false
- System.out.println(s2.equals(s3)); //true
复制代码
解释 参考5
7.
- String s1 = "ab";
- String s2 = s1 + "c";
- String s3 = new String("abc");
- System.out.println(s2==s3); //false
- System.out.println(s2.equals(s3)); //true
复制代码
解释 参考5
8.
- final String s1 = "ab";
- String s2 = s1 + "c";
- String s3 = "abc";
- System.out.println(s2==s3); //true
- System.out.println(s2.equals(s3)); //true
复制代码
解释
final String s1 = "ab"; final 修饰的s1为常量, s1相当于常量池中的"ab";
String s2 = s1 + "c"; 相当于 String s2 = "ab" + "c"; 按照4理解即可。
9 .
- final String s1 = new String("ab");
- String s2 = s1 + "c";
- String s3 = "abc";
- System.out.println(s2==s3); //false
- System.out.println(s2.equals(s3)); //true
复制代码
解释
final String s1 = new String("ab"); 常量s1表示堆中的一个String对象不可指向其他的对象。
String s2 = s1 + "c"; 编译器无法确认s1指向的对象的值是否可以发生变化所以不会进行优化。s2指向了堆内存中的一个String对象
String s3 = "abc"; 在常量池中创建了一个对象 "abc" ,s3指向"abc"。
所以 s2==s3 为false
10.
- final String s1 = new String("ab");
- final String s2 = new String("ab");
- System.out.println(s2==s3); //false
- System.out.println(s2.equals(s3)); //true
复制代码
解释 :
final String s1 = new String("ab"); s1表示堆中的一个String对象且不可指向其他的对象。
final String s2 = new String("ab"); s2表示堆中的另一个String对象且不可指向其他的对象。和s1指向的不是同一个对象
所以s2 == s3 返回false。
equals参考1
总结: 堆中存放使用new关键字创建的对象。字符串是一个特殊包装类,其引用是存放在栈里的,而对象内容必须根据创建方式不同定(常量池和堆),有的是编译期就已经创建好,存放在字符串常量池中,而有的是运行时才被创建。使用new关键字,存放在堆中。
|
|