String部分源码分析
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了String部分源码分析相关的知识,希望对你有一定的参考价值。
最近想处理上传文件时request包含的混合信息,得到的流可以部分解析成String部分依旧当二进制流处理
于是把BufferedInputStream和String的源码相关部分都读了一下
String是final修饰的类这个大家应该都知道,其中主要的char[] value也是final修饰的
大概看了下字符串驻留结合自己的理解,我试着讲下白话文= =#
String a="abc";
这样是在池内先搜索"abc"如果没有创建一个字符串"abc"并a引用之
String b=new String("abc");
也是在池内先搜索"abc"如果没有创建一个字符串"abc",但是然后将"abc"的value引用传给这个新创建的String(final修饰的变量不会被隐式初始化,获得初始值后无法改变)
private final char value[];
public String(String original) { this.value = original.value; this.hash = original.hash; }
至于String c="a"+"bc";编译器直接就是当成String c="abc";
注意String中value是取不到的,是为了避免对value数组的修改(引用是final不可变,数组内元素可以变更)
public char[] toCharArray() { // Cannot use Arrays.copyOf because of class initialization order issues char result[] = new char[value.length]; System.arraycopy(value, 0, result, 0, value.length); return result; }
上面的方法也只是取了一个复制的数组
类似的许多方法都是创建一个新的String、新的char[]
接下来看下indexOf(String str)
public int indexOf(String str) { return indexOf(str, 0); }
public int indexOf(String str, int fromIndex) { return indexOf(value, 0, value.length, str.value, 0, str.value.length, fromIndex); }
fromIndex表示从哪里开始搜索 类似的lastIndexOf(String str)则是一样的算法从后往前搜索
回到indexOf(String str,int fromIndex),其中引用了indexOf(char[] source, int sourceOffset, int sourceCount,char[] target, int targetOffset, int targetCount,int fromIndex)
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; }
if (source[i] != first) { while (++i <= max && source[i] != first); }
寻找与目标首字母相同的,如果一直到末尾都没找到就return -1不然得到第一个满足条件的索引i
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; }
source中索引i+1到i+targetCount的元素,与target中索引targetOffset+1到targetOffset+targetCount(即需要比较的两个子数组的第二个元素开始到尾)
试着对比,如果都相等最后j就会等于end,如果中间有不同就到回到上一个if语句块中找第二个首字母相同的,依此类推。
i-sourceOffset是在sourceCount个元素的子数组中满足条件的索引
= =#用了下画图好累啊~
以上是关于String部分源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向整体加固脱壳 ( DEX 优化流程分析 | DexPrepare.cpp 中 dvmOptimizeDexFile() 方法分析 | /bin/dexopt 源码分析 )(代码片段
Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段
String-StringBuffer-StringBuilder的区别和源码分析