A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

本帖最后由 l493062120 于 2016-4-7 19:05 编辑


1.
  1. String s1 = "abc";
  2.    String s2 = "abc";
  3.    System.out.println(s1==s2);          //true
  4.    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.
  1. String s1 = "abc";
  2.    String s2 = new String("abc");
  3.    System.out.println(s1==s2);          //false
  4.    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.
  1. String s1 = new String("abc");
  2.    String s2 = new String("abc");
  3.    System.out.println(s1==s2);          //false
  4.    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.
  1. String s1 = "ab" + "c";
  2.    String s2 = "abc";
  3.    System.out.println(s1==s2);          //true
  4.    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.
  1. String s1 = "ab";
  2.    String s2 = s1 + "c";
  3.    String s3 = "abc";
  4.    System.out.println(s2==s3);          //false
  5.    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  

  1.    String s1 = new String("ab");
  2.    String s2 = s1 + "c";
  3.    String s3 = "abc";
  4.    System.out.println(s2==s3);          //false
  5.    System.out.println(s2.equals(s3));        //true
复制代码

解释   参考5

7.
  1. String s1 = "ab";
  2.    String s2 = s1 + "c";
  3.    String s3 = new String("abc");
  4.    System.out.println(s2==s3);          //false
  5.    System.out.println(s2.equals(s3));        //true
复制代码

解释   参考5


8.
  1. final String s1 = "ab";
  2.    String s2 = s1 + "c";
  3.    String s3 = "abc";
  4.    System.out.println(s2==s3);          //true
  5.    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 .
  1. final String s1 = new String("ab");
  2.    String s2 = s1 + "c";
  3.    String s3 = "abc";
  4.    System.out.println(s2==s3);          //false   
  5.    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.
  1. final String s1 = new String("ab");
  2.    final String s2 = new String("ab");
  3.    System.out.println(s2==s3);          //false
  4.    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关键字,存放在堆中。



2 个回复

倒序浏览
强哥  绝啦!!!!!!!!{:2_36:}
回复 使用道具 举报
有技术含量,帮助很大
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马