不可变的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的源码:
3.不可变的优点:
1.不可变,天生线程安全,不用使用同步。
2.hashcode确定、提前缓存hashcode,不需要重新计算,处理速度很快,很适合做键值。
4.通过反射机制手段可以改变不可变
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类是不可变的?
- 为什么String类是不可变的?
- Java第5课(可变的String类---StringBuffer类)
- Java技术——String类为什么是不可变的
- 为什么String类是不可变的
- Java的string类为什么是不可变的
- Java技术——String类为什么是不可变的
- 为什么String类是不可变的?
- String类为什么要设计成不可变的
- 为什么String类是不可变的?
- 为什么String类是不可变的?
- 为什么String类是不可变的
- lwj_C#_string类方法 可变字符串
- java中String类为什么要设计成不可变的
- String类到底可不可变
- 为什么String类是不可变的
- String类不可变以及不可变类总结
- 为什么String类是不可变的?
- 为什么String类是不可变的?