java源码学习之String(一)

刚刚进入实习阶段,发现公司中大神一大片,自己一只菜鸡还需要努力学习啊。所以向公司以为前辈请教了学习方向以后,开始认真学习一下。首先是javaSE基础,从String开始吧。自己也是一边学习一边做笔记。所以错误的地方希望网友指正我会虚心接受。

/**
     * Compares this string to the specified object.  The result is {@code
     * true} if and only if the argument is not {@code null} and is a {@code
     * String} object that represents the same sequence of characters as this
     * object.
     *
     * @param  anObject
     *         The object to compare this {@code String} against
     *
     * @return  {@code true} if the given object represents a {@code String}
     *          equivalent to this string, {@code false} otherwise
     *
     * @see  #compareTo(String)
     * @see  #equalsIgnoreCase(String)
     */
    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;
    }

上面是从jdk中复制的String中的equals方法的源码。equals在String类中被重写了。首先判断传入的Object对象实例和本对象实例的对象内存地址是否相同,相同的话说明是同一个对象的引用,返回true。然后判断传入的anObject是否是String类的实例,是的话将anObject赋值给anotherString,如果两个字符串的长度length(String的另一个重点,接下来会讲到)相等,继续下一步,value是String类中定义的一个字符型数组常量,String类保存字符串的形式还是一字符型数组的形式来保存的,value[ ]就是String字符串保存的地方,然后逐一对比两个字符串中的字符value[i]是否是相同值的字符。如果全部都是则说明两个字符串相同。String重写了Object的equals方法,因为主要体现在if(v1[i]!=v2[i]),就将equals方法变成了基本类型char内容的比较而不是比较内存值了。

 public String replace(char oldChar, char newChar) {
        if (oldChar != newChar) {
            int len = value.length;
            int i = -1;
            char[] val = value; /* avoid getfield opcode */

            while (++i < len) {
                if (val[i] == oldChar) {
                    break;
                }
            }
            if (i < len) {
                char buf[] = new char[len];
                for (int j = 0; j < i; j++) {
                    buf[j] = val[j];
                }
                while (i < len) {
                    char c = val[i];
                    buf[i] = (c == oldChar) ? newChar : c;
                    i++;
                }
                return new String(buf, true);
            }
        }
        return this;
    }

接下来是replace方法。replace传入的参数是两个char类型的参数,用于将字符串中的oldChar更新为newChar。当oidChar不等于newChar时,找到String中和oldChar相同的字符之后将字符的下标赋值给i;如果这个字符的位置是在字符串中的话,将字符串中的value数组复制到buf数组中,然后从第一个和oldChar重复的字符开始依次对比是否还有重复的字符,有的话就将字符的值重新赋值为newChar直到最后。返回一个buf更新字符后的新数组初始化的字符串。更新完成

最后总结一下String通过各种方式建立字符串时内存的状态

String s = new String("abc");  
String s1 = "abc"; 
String s2 = s.intern();
String s3 = "ab";  
String s4 = "a";  
String s5 = s1 + "b";  
String s6 = "ab";
String s7 = "ad";  
String s8 = "a" + "d";  
String s9 = "ad";
s:会在java堆中创建对象

s1:是直接量的字符串。编译时就确定为常量的字符串首先在常量池中寻找是否存在,如果存在将si的引用指向此字符串,不存在的话则新建一个。

s2:首先去常量池中寻找是否存在“abc”这个字符串,如果存在的话,就将s2指向这个字符串的引用,不存在则新增

s5:s5的内部实现是s5=StringBuilder(s1).append("b").toString();所以会在java堆中创建对象

s8:因为是直接常量,所以在编译时就会将两个字符串连接成一个,s7==s8返回true




你可能感兴趣的:(java学习笔记)