刚刚进入实习阶段,发现公司中大神一大片,自己一只菜鸡还需要努力学习啊。所以向公司以为前辈请教了学习方向以后,开始认真学习一下。首先是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