您的位置:首页 > 其它

不可变的String类

2017-12-09 17:23 99 查看
String类是不可变的

StringBuffer(线程安全、慢)和StringBuilder(非线程安全、快)是可变的

1.创建String对象的两种方式

(1)直接赋值:String str=”abc”;

采用直接赋值的方式创建一个字符串时,JVM首先会去字符串常量池中查找是否存在”abc”这个对象,如果不存在,则在字符串池中创建”aaa”这个对象,然后将池中“这个对象的引用地址返回给字符串常量str,这样str会指向池中这个字符串对象;如果存在,则不创建任何对象,直接将池中这个对象的引用地址返回,赋给字符串常量str。

(2)使用new关键字创建:String str= new String(“abc”);

采用new关键字新建一个字符串对象时,JVM首先在字符串常量池中查找有没有”abc”这个字符串对象,如果有,则不在池中再去创建这个对象了,直接在堆中创建一个字符串对象,然后将堆中的这个对象的地址返回赋给引用str,这样,str3就指向了堆中创建的这个”aaa”字符串对象;如果没有,则首先在字符串池中创建一个”abc”字符串对象,然后再在堆中创建一个”abc”字符串对象,然后将堆中这个”aaa”字符串对象的地址返回赋给str引用,这样,str指向了堆中创建的这个字符串对象。

2.String对象是不可变的,但它可以返回一个新的字符串对象。

String的源码:

//1.string类被final修饰,不可以被继承
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence
{
/** The value is used for character storage. */
private final char value[];//2.内部所有成员变量都为私有的,且没有set方法
/** The offset is the first index of the storage that is used. */
private final int offset;
/** The count is the number of characters in the String. */
private final int count;
/** Cache the hash code for the string */
private int hash; // Default to 0
....
public String(char value[]) {
this.value = Arrays.copyOf(value, value.length); // deep copy操作
}
...
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;//返回对象的copy,而不是对象的引用,不可改变string
}
...
}


3.不可变的优点:

1.不可变,天生线程安全,不用使用同步。

2.hashcode确定、提前缓存hashcode,不需要重新计算,处理速度很快,很适合做键值。

4.通过反射机制手段可以改变不可变

package com.wugeek.test;

import java.lang.reflect.Field;

/**
* @author 作者 :peanut.w
* @version 创建时间:2017年12月7日 上午9:52:35 类说明
*/
public class UseOffice {
public static void main(String[] args) throws Exception {
final String str = "abcd";
System.out.println(str.hashCode());
edit(str, "efgh");
System.out.println(str.hashCode());
}

public static void edit(final String str, String newValue) throws Exception {
Field field = String.class.getDeclaredField("value");//获取该类下的所有字段,包括私有字段
field.setAccessible(true);//处理类中的privatez
field.set(str, newValue.toCharArray());
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  String类 创建String