java程序员

Java基础(四) | 形影不离的String字符串

2017-06-23  本文已影响227人  采风JS

字符串,一个深受折磨的朋友。它并不是基本数据类型,而是一种对象。关于此对象,常涉及到比较、访问、修改操作,是程序员编码的基本功。今天,将String进行深入剖析,做一个合格的蓝颜知己。

1. " "、null和new String()的区别

String s1 = null; 
// 未分配内存,未创建引用,未初始化
String s2 = " "; 
String s3 = new String();
// 完成初始化,分配内存,创建引用,但其值为空

2. 字符串池

创建字符串对象时,在字符串池中寻找具有相同字面值的对象,如果存在,则返回该对象的引用;如果不存在,则创建对象置于字符串池中,并且返回新创建对象的引用;

字符串池的存在,减少内存开销,所以推荐使用非new的方式,使用String s = "bat"的方式;

3. String、StringBuffer和StringBuilder

4. String真是不可变对象吗?

可以优先考虑一下这篇博客:Java中的String为什么是可变的?

// String类的源码,jdk1.8
private final char value[]; // String类可以看作是对不可变数组的封装
private int hash; 
// 基于反射改变String
    public static void main(String[] args) throws Exception{
        String name = "Xi Dian";
        Field value = String.class.getDeclaredField("value");
        value.setAccessible(true);
        char[] c = (char[]) value.get(name);
        c[2] = '_';
        System.out.println(name); // 打印结果为: Xi_Dian
    }

5. 深入理解拼接操作

// 编译器对"+"操作符进行优化,下面两者等效
str += "b";
str = new StringBuilder().append("b").toString();
// jdk1.8源码 concat方法
    public String concat(String str) {
        int otherLen = str.length();
        if (otherLen == 0) {
            return this;
        }
        // 此处的len为原字符串的长度
        int len = value.length;
        char buf[] = Arrays.copyOf(value, len + otherLen);
        // str将从0到自身length长度拷贝到buf中从len开始之后的位置
        str.getChars(buf, len);
        // 新建字符串
        return new String(buf, true);
    }
    void getChars(char dst[], int dstBegin) {
        System.arraycopy(value, 0, dst, dstBegin, value.length);
    }
// jdk1.8的源码 append()方法
    public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {
        if (srcBegin < 0) {
            throw new StringIndexOutOfBoundsException(srcBegin);
        }
        if (srcEnd > value.length) {
            throw new StringIndexOutOfBoundsException(srcEnd);
        }
        if (srcBegin > srcEnd) {
            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);
        }
        System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
    }

    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        // 从value的count索引开始,逐个添加str字符数组
        str.getChars(0, len, value, count);
        count += len;
        // 并不产生新的对象
        return this;
    }
上一篇下一篇

猜你喜欢

热点阅读