java String类源码分析 尚学堂115

String 类对象代表不可变的Unicode字符序列,因此我们可以将String对象称为“不可变对象”。

String类的substring方法

public String substring(int beginIndex)

 

返回一个字符串,该字符串是此字符串的子字符串。 子字符串以指定索引处的字符开头,并扩展到该字符串的末尾。

 public String substring(int beginIndex, int endIndex)

 

返回一个字符串,该字符串是此字符串的子字符串。 子串开始于指定beginIndex并延伸到字符索引endIndex - 1 。 因此,子串的长度为endIndex-beginIndex


public class Test{
	public static void main(String[] args) {
		String str = "abcdefg";
		String b1 = str.substring(2, 5);
		System.out.println(b1);
		String b2 = str.substring(3);
		System.out.println(b2);
	}
}

 输出结果:

cde
defg

substring()是对字符串的截取操作,但本质是读取原字符串内容生成了新的字符串。 

substring方法源码:

public String substring(int beginIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        int subLen = value.length - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return (beginIndex == 0) ? this : new String(value, beginIndex, subLen);
    }

public String substring(int beginIndex, int endIndex) {
        if (beginIndex < 0) {
            throw new StringIndexOutOfBoundsException(beginIndex);
        }
        if (endIndex > value.length) {
            throw new StringIndexOutOfBoundsException(endIndex);
        }
        int subLen = endIndex - beginIndex;
        if (subLen < 0) {
            throw new StringIndexOutOfBoundsException(subLen);
        }
        return ((beginIndex == 0) && (endIndex == value.length)) ? this
                : new String(value, beginIndex, subLen);
    }

其中,String构造方法源码:

public String(char value[], int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // 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);
    }

其中,copyOfRange方法源码:

    public static char[] copyOfRange(char[] original, int from, int to) {
        int newLength = to - from;
        if (newLength < 0)
            throw new IllegalArgumentException(from + " > " + to);
        char[] copy = new char[newLength];
        System.arraycopy(original, from, copy, 0,
                         Math.min(original.length - from, newLength));
        return copy;
    }

 其中,arraycopy是一个本地方法(native)。

API说明:

String

 

public String(byte[] bytes,
              int offset,
              int length)

通过使用平台的默认字符集解码指定的字节子阵列来构造新的String 。 新的String的长度是字符集的函数,因此可能不等于子数组的长度。

指定字节在默认字符集中无效时,此构造函数的行为是未指定的。 当需要更多的解码过程控制时,应使用CharsetDecoder类。

参数

bytes - 要解码为字符的字节

offset - 要解码的第一个字节的索引

length - 要解码的字节数

异常

IndexOutOfBoundsException - 如果 offsetlength参数的索引字符在 bytes数组的边界之外

从以下版本开始:

JDK1.1

 


public class Test{
	public static void main(String[] args) {
		char value[] = {'s', 't', 'u', 'd', 'y', ' ', 'j', 'a', 'v', 'a'};
		String s = new String(value, 3, 5);
		System.out.println(s);
	}
}

输出结果:

dy ja

 字符串比较

public static void main(String[] args) {
        //编译器做了优化,直接在编译的时候将字符串进行拼接
        String str1 = "hello" + " java";//相当于str1 = "hello java";
        String str2 = "hello java";
        System.out.println(str1 == str2);//true
        String str3 = "hello";
        String str4 = " java";
        //编译的时候不知道变量中存储的是什么,所以没办法在编译的时候优化
        String str5 = str3 + str4;
        System.out.println(str2 == str5);//false
    }

输出结果:

true
false 

StringBuffer和StringBuilder

StringBuffer和StringBuilder非常类似,均代表可变的字符序列。 这两个类都是抽象类AbstractStringBuilder的子类,方法几乎一模一样。

public class Test {
    public static void main(String[] args) {
        StringBuilder str = new StringBuilder("abcdefg");
        System.out.println(Integer.toHexString(str.hashCode()));
        System.out.println(str);
        str.setCharAt(2, 'M');
        System.out.println(Integer.toHexString(str.hashCode()));
        System.out.println(str);
    }
}

输出结果:

2f7a2457
abcdefg
2f7a2457
abMdefg 

地址一样,说明是同一个对象,是可变的字符必须列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值