String类型的等值比较和内容比较

关于String类型的等值比较和内容比较,是学习java甚至任何编程语言所共同的常见问题,理解String类型的等值比较和内容比较也是面试经常问到的问题。

字符串等值比较

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

     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;
    }

首先,如上述String的源码可以知道的是,java中等值比较,就是“==”比较,比较的是地址。字符串本质上是final修饰的字符数组,也就是说,当创建字符串对象时,字符串的引用是常量,但它每一个对象的值可以改变。

字符串内容比较

如上述String的源码可以知道的是,字符串的内容比较就是所谓的字符串的equals()方法,比较的是两个字符串对象储存的值,也就是内容是否相等,所谓内容相同,就是字符串每一个位置的字符相同。这里值得注意的是String重写了Object的equals()方法(Object的==与equals()是一样的)

地址分配图示

很明显str1和str2的地址相同,他们与str3的地址不相同,但是str3通过方法intern(),可以强制入池,和str1和str2的地址相同。

结论

字符串:默认为常量------------进常量池

String val = “xxx”;---------------------------默认入池

String val = new String(“xxx”);--------------------------默认入堆,但可以通过intern()强制入池(堆里的对象还在)

String 类的常见面试问题
面试题一:
        String s1 = "abc";            // 常量池
        String s2 = new String("abc");     // 堆内存中
        System.out.println(s1==s2);        // false两个对象的地址值不一样。
        System.out.println(s1.equals(s2)); // true

       
面试题二:

        String s1="a"+"b"+"c";
        String s2="abc";
        System.out.println(s1==s2);
        System.out.println(s1.equals(s2));
java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。
面试题三:

        String s1="ab";
        String s2="abc";
        String s3=s1+"c";
        System.out.println(s3==s2);         // false
        System.out.println(s3.equals(s2));  // true
先在常量池中创建 ab ,地址指向 s1, 再创建 abc ,指向 s2。对于 s3,先创建StringBuilder(或 StringBuffer)对象,通过 append 连接得到 abc ,再调用 toString() 转换得到的地址指向 s3。故 (s3==s2) 为 false。
java 中常量优化机制,编译时 s1 已经成为 abc 在常量池中查找创建,s2 不需要再创建。

猜你喜欢

转载自blog.csdn.net/BigData_Hobert/article/details/106532940