您好,欢迎来到三六零分类信息网!老站,搜索引擎当天收录,欢迎发信息

String源码的实例解读

2024/3/11 23:32:41发布23次查看
string类内部维护了一个char[]类型的value用来存储字符串,相对来说源码较为简单些。
1.不可变性string的不可变主要体现在三个方面:
string类被定义为final类型,不可被继承
string中的value[]被定义为final
string中的所有生成新的string的操作底层都调用array.copy或者system.copy来生成一个新的string对象
2.构造函数,string的构造函数较为简单,但以下几个较为特殊    public string(string original) {         this.value = original.value;         this.hash = original.hash;     }          string(char[] value, boolean share) {         // assert share : unshared not supported;         this.value = value;     }
以上两个是较为特殊的一类构造函数,第一个用一个现成的string来初始化一个新的string对象,构造方法直接将新的string对象的value指向老的value对象。由于string是不可变的,所以这里不需要重新copy一份value的对象。第二个构造方法看似会破坏string类型的不可变性(当参数value变化时string也会变化),但该构造方法并没有声明为public,只允许在包内使用,被声明为public的string(char value[])底层调用的是array.copy来实现底层数据拷贝的,上述的两个构造函数已经不建议使用
    public string(char value[], int offset, int count) {         if (offset < 0) { throw new stringindexoutofboundsexception(offset); } if (count < 0) { throw new stringindexoutofboundsexception(count); } // note: offset or count might be near -1>>>1.         if (offset > value.length - count) {             throw new stringindexoutofboundsexception(offset + count);         }         this.value = arrays.copyofrange(value, offset, offset+count);     }
上面这个构造函数较为典型,很多其他的构造函数都与其类似或者底层调用了该构造函数,入参是一个char数组(byte[]),offset偏移位置及count偏移量。底层调用arrays.copy函数来进行深度复制。
    public string(stringbuffer buffer) {         synchronized(buffer) {  //保证线程安全             this.value = arrays.copyof(buffer.getvalue(), buffer.length());         }     }          public string(stringbuilder builder) {         this.value = arrays.copyof(builder.getvalue(), builder.length());     }
上述两个构造函数入参分别是stringbuffer和stringbuilder,底层都是调用arrays.copyof,唯一不同的是stringbuffer是线程安全的,所有调用时需要用synchronized关键字。
3.其他方法    static int indexof(char[] source, int sourceoffset, int sourcecount,             char[] target, int targetoffset, int targetcount,             int fromindex) {         if (fromindex >= sourcecount) {             return (targetcount == 0 ? sourcecount : -1);         }         if (fromindex < 0) { fromindex = 0; } if (targetcount == 0) { return fromindex; } char first = target[targetoffset]; int max = sourceoffset + (sourcecount - targetcount); for (int i = sourceoffset + fromindex; i <= max; i++) { /* look for first character. */ if (source[i] != first) { while (++i <= max && source[i] != first); } /* found first character, now look at the rest of v2 */ if (i <= max) { int j = i + 1; int end = j + targetcount - 1; for (int k = targetoffset + 1; j < end && source[j] == target[k]; j++, k++); if (j == end) { /* found whole string. */ return i - sourceoffset; } } } return -1; } static int lastindexof(char[] source, int sourceoffset, int sourcecount, char[] target, int targetoffset, int targetcount, int fromindex) { /* * check arguments; return immediately where possible. for * consistency, don't check for null str. */ int rightindex = sourcecount - targetcount; if (fromindex < 0) { return -1; } if (fromindex > rightindex) {             fromindex = rightindex;         }         /* empty string always matches. */         if (targetcount == 0) {             return fromindex;         }         int strlastindex = targetoffset + targetcount - 1;         char strlastchar = target[strlastindex];         int min = sourceoffset + targetcount - 1;         int i = min + fromindex;         startsearchforlastchar:         while (true) {             while (i >= min && source[i] != strlastchar) {                 i--;             }             if (i < min) { return -1; } int j = i - 1; int start = j - (targetcount - 1); int k = strlastindex - 1; while (j > start) {                 if (source[j--] != target[k--]) {                     i--;                     continue startsearchforlastchar;                 }             }             return start - sourceoffset + 1;         }     }
indexof和lastindexof主要是index和lastindex函数的底层调用,通读代码会发现底层实现并没有特别牛逼的kmp算法,仍然是一个字符一个字符扫描实现的。其中lastindexof还是用了continue startsearchforlastchar;相对来说比较少见。
    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;                 }             }             //如果找不到则返回this             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++;                 }                 //返回新的string,利用上述包内的非public构造函数                 return new string(buf, true);             }         }         return this;     }
replace用于将string对象中的一个字符替换为另一个字符,如果找不到制定的字符则返回本身,如果找到则会另建一个新的string对象返回。
---恢复内容结束---
以上就是string源码的实例解读的详细内容。
该用户其它信息

VIP推荐

免费发布信息,免费发布B2B信息网站平台 - 三六零分类信息网 沪ICP备09012988号-2
企业名录 Product