String 中 == 和 equal()笔试题

        String test1 = new String(“张三”); 这种方式会产生两个对象:一个是 “张三”String pool中产生的一个值为 “张三” 的对象,另一个是在堆中产生一个值为 “张三” 的对象,这个对象是String Pool中的 “张三” 的拷贝,上述中 test1 最后指向的是堆中的对象的地址,所以,当两个new String() 对象进行 == 比较,是堆中的两个对象的地址的比较,所以, test1 == test2 为false

String test1 = new String("张三");
        String test2 = new String("张三");
        System.out.println(test1 == test2);  // false
        System.out.println(test1.equals(test2));  // true

        String test3 = “2”; 会在String pool中存创建一个 “2”字符串对象 ,并把地址给 test3 ,String test4 = “2”; 会在Stirng pool中找有没有 “2” 这个字符串对象,如果没有,创建一个,如果有的话,返回这个已存在的字符串对象的地址 ,所以,test3test4都指向通过同一个String pool中字符串对象的地址,所以 == 比较为true

        String test3 = "2";
        String test4 = "2";

        System.out.println(test3 == test4);   // true
        System.out.println(test3.equals(test4));  // true

        当 声明的对象是类似于 String s = “hello”; 这种形式的,是在spring pool中创建一个 “hello”字符串常量对象,当下一次有 一个类似于String s1 = “hello”; 的时候,会先从spring pool 中找是否已经存在**“hello”** 这个常量对象 (equal()), 如果已经存在,返回这个地址,如果不存在,创建一个,返回地址.
        如果是以 string s3 = “hel” + “lo”; 的形式声明字符串,会先把右面的拼接在一起,产生一个新的常量对象 “hello”, 然后去String pool中查,如果已经存在, 返回的是已经存在的 “hello” 的地址,所以,当变量hello通过 == 比较的时候,两边的地址相同,所以为true
        当声明的对象 = 右面两个参数中有一个是对象两个都是对象的形式 例如:

	String s4 = "hel";
	String s5 = "lo";	
	String s6 = "hel"+s5; 或 String s7 = s4 + s5;

        此时会在堆中新建一个对象,这个对象的值是右面两个参数拼接后的值,返回的是中新的对象的地址, 所以与 变量 hello 的地址不同所以为false.

     String hello = "hello";
     String hel = "hel";
     String lo = "lo";

     System.out.println(hello == "hel" + "lo"); // true
     System.out.println(hello == "hel" + lo);   // false

     System.out.println(hello.equals("hel" + "lo"));  // true
     System.out.println(hello.equals("hel" + lo));   // true

        String test5 = “张三”; 中的 test5 保存的是String pool中的地址
        String test2 = new String(“张三”);test2 保存的是堆中的地址,所以两者通过 == 比较,为 false, 但是使用 equal() 时比较的是不同地址上内容的比较,所以为true

       String test5 = "张三";
       System.out.println(test5 == test2);  // false
       System.out.println(test5.equals(test2)); // true

        String test10 = test6 + test7; 会在堆中产生一值为 “abcd” 的对象,而 String test9 = “abcd”;这种是在String pool 中产生一个字符串对象,返回的值String pool中的地址,所以这个比较两个不同地方的地址,答案肯定是false.

        String test6 = "ab";
        String test7 = "cd";
        String test8 = "ab" + "cd";
        String test9 = "abcd";
        String test10 = test6 + test7;

        System.out.println(test8 == test9); // true
        System.out.println(test8 == test10); // false
        System.out.println(test9 == test10); // false

        String 中的 equal() 比较的是两个对象地址所指向的内容的比较, 源码中,先通过 == 比较引用地址,如果相同,直接返回true,判断被比较的是否是字符串,如果不是,直接返回false 然后比较两个对象内容的长度,如果不同,返回false,然后再字符串一个一个内容的比较,有不同的,返回false,最后,内容相同,返回true.

        System.out.println("-----------------------");
        System.out.println(test8.equals(test9));  // true
        System.out.println(test8.equals(test10));  // true
        System.out.println(test9.equals(test10));  // true

        String的equal()方法源码:

public boolean equals(Object anObject) {
		// 比较两个地址是否相同
       if (this == anObject) {
           return true;
       }
       // 比较是否是字符串类型
       if (anObject instanceof String) {
           String anotherString = (String)anObject;
           int n = value.length;
           // 比较两个对象内容的长度
           if (n == anotherString.value.length) {
               char v1[] = value;
               char v2[] = anotherString.value;
               int i = 0;
               while (n-- != 0) {
               // 比较字符串每一个字符
                   if (v1[i] != v2[i])
                       return false;
                   i++;
               }
               return true;
           }
       }
       return false;
   }

猜你喜欢

转载自blog.csdn.net/kai3123919064/article/details/88959941