String字符串的“==”和equals 比较,看这篇差不多就够了!

  1 package day2_7;
  2 
  3 import org.junit.Test;
  4 
  5 /**
  6  * String:字符串,一般使用一对 "" 引起来表示
  7  *
  8  * public final class String
  9  *     implements java.io.Serializable, Comparable<String>, CharSequence {
 10  *     private final char value[];
 11         ....
 12     }
 13  *
 14  * 1.String类声明为final,说明不可被继承
 15  * 2.String继承了Serializable,说明是可序列化的
 16  *   String继承了Comparable,说明是可以比较大小的
 17  * 3.String内部定义了 private final char value[];用于存储字符串数据
 18  * 4.String代表不可变的字符序列,简称:不可变性
 19  *   体现:1.当对字符串重新赋值时,需要重新指定内存区域赋值,不能使用原有的value进行赋值
 20  *        2.当对现有字符串进行连接操作时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
 21  *        3.当调用replace()修改指定字符或字符串时,也需要重新指定内存区域赋值,不能使用原有的value进行赋值
 22  * 5.通过字面量的方式(区别于new的)给一个字符串赋值,此时的字符串值声明在字符串常量池中
 23  * 6.字符串常量池是不会存储相同内容的字符串的
 24  *
 25  *
 26  * @Author Tianhao
 27  * @create 2021-02-07-17:31
 28  */
 29 public class StringTest {
 30 
 31     @Test
 32     public void test1() {
 33         String s1 = "abc"; //字面量的定义方式
 34         String s2 = "abc";
 35         System.out.println(s1 == s2); //比较地址值  true
 36         s1 = "hello";
 37         System.out.println(s1 == s2); //比较地址值  false
 38         System.out.println(s1); //hello
 39         System.out.println(s2); //abc
 40 
 41         System.out.println("*****************");
 42         String s3 = "abc";
 43         s3 += "def";
 44         System.out.println(s3); //abcdef
 45         System.out.println(s2); //abc
 46 
 47         System.out.println("****************");
 48         String s4 = "abc";
 49         String s5 = s4.replace("ab", "de");
 50         System.out.println(s5); //dec
 51         System.out.println(s4); //abc
 52 
 53     }
 54 
 55     /**
 56      *String的实例化方式
 57      * 方式一:通过字面量定义的方式
 58      * 方式二:通过new + 构造器的方式
 59      *
 60      *
 61      * 面试题: String s = new String("abc"); 通过这种方式创建对象,在内存中创建了几个对象?
 62      *      两个:一个是new的String对象结构,
 63      *           另一个是其类中的char[] value成员变量对应的方法区字符串常量池中的数据"abc"
 64      */
 65 
 66     @Test
 67     public void test2() {
 68         //通过字面量定义的方式
 69         // 此时的s1、s2指向的数据JaveEE都声明在方法区中的字符串常量池中
 70         String s1 = "JavaEE";
 71         String s2 = "JavaEE";
 72 
 73         //通过new + 构造器的方式
 74         //// 此时的s3、s4保存的地址值,是数据在堆空间开辟空间以后对应的地址值
 75         String s3 = new String("JavaEE");
 76         String s4 = new String("JavaEE");
 77 
 78         System.out.println(s1==s2);//true
 79         System.out.println(s1==s3);//false
 80         System.out.println(s1.equals(s3)); //true
 81         System.out.println(s1==s4);//false
 82         System.out.println(s1.equals(s4)); //true
 83         System.out.println(s3==s4);//false
 84         System.out.println(s3.equals(s4)); //true
 85 
 86 
 87         System.out.println("*********************");
 88 
 89         Person p1 = new Person("Tom", 23);
 90         Person p2 = new Person("Tom", 23);
 91         Person p3 = new Person(new String("Tom"), 23);
 92         //每new一次,堆就重新开辟一个空间,把地址值赋给引用对象,地址值都是不一样的
 93         System.out.println(p1 == p2); //false
 94         //因为Person类没有重写Object的equals(),所以默认还是 == ,比较对象地址值
 95         System.out.println(p1.equals(p2));//false
 96         //两个对象都是通过字面量赋值,指向方法区字符串常量池中同一个数据Tom,所以地址值相同
 97         System.out.println(p1.name == p2.name);//true
 98         //因为String类重写了Object的equals(),比较的是字符串内容
 99         System.out.println(p1.name.equals(p2.name)); //true
100         //每new一次,堆就重新开辟一个空间,把地址值赋给引用对象,地址值都是不一样的
101         System.out.println(p1 == p3); //false
102         //p1的name是通过字面量赋值,p3的name是通过new+构造器方式赋值
103         //前者是指向方法区常量池中的数据Tom,后者是指向堆空间的String对象的char[]类型的成员变量value
104         //显然两者的地址值是不同的
105         System.out.println(p1.name == p3.name);//false
106         //因为String类重写了Object的equals(),比较的是字符串内容
107         System.out.println(p1.name.equals(p3.name)); //true
108 
109     }
110 
111 
112     /**
113      *
114      * 结论:
115      * 1.常量与常量的拼接结果在常量池。且常量池中不会存在相同内容的常量
116      * 2.只要其中一个是变量,结果就在堆中
117      * 3.如果拼接的结果调用intern(),返回值就在常量池中
118      *
119      */
120 
121     @Test
122     public void test3() {
123         String s1 = "Hello";
124         String s2 = "World";
125         String s3 = "HelloWorld";
126         String s4 = "Hello" + "World";
127         String s5 = "Hello" + s2;
128         String s6 = s1 + "World";
129         String s7 = s1 + s2;
130         String intern = s5.intern();
131 
132         System.out.println(s3 == s4);
133 
134         System.out.println("*** 带变量的拼接 ***");
135         System.out.println(s3 == s5);
136         System.out.println(s3 == s6);
137         System.out.println(s3 == s7);
138         System.out.println(s4 == s5);
139         System.out.println(s4 == s6);
140         System.out.println(s4 == s7);
141         System.out.println(s5 == s6);
142         System.out.println(s5 == s7);
143         System.out.println(s6 == s7);
144 
145         System.out.println("**** intern()方法 *****");
146         System.out.println(s3 == intern);
147         System.out.println(s4 == intern);
148         System.out.println(s5 == intern);
149         System.out.println(s6 == intern);
150     }
151 
152 }
原文地址:https://www.cnblogs.com/zui-ai-java/p/14386489.html