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 源码分析 )(代码片段

String 部分源码分析

Android 事件分发事件分发源码分析 ( Activity 中各层级的事件传递 | Activity -> PhoneWindow -> DecorView -> ViewGroup )(代码片段

String-StringBuffer-StringBuilder的区别和源码分析

STRING-STRINGBUFFER-STRINGBUILDER的区别和源码分析

jdk源码分析——String类