字符串是编程中应用到最多的一个数据类型,简单实用,但是深入理解它们,会给我们带来更多好处。
字符串缓存池:
为了节省内存,提高资源的复用,java中引入了字符串缓存池的概念。
缓存池中的字符串是不可回收的:
在缓存池中的字符串是不会被垃圾回收机制回收的,基本都是常驻内存,所以过多食用String类,可能会出现内存溢出(下面会讲)。
怎么样才会存进缓存池:
- 直接量赋值创建对象
在Java,基本包装类型String,Long,Float,Boolean.......都可以利用直接量创建对象。
String用直接量进行创建对象的时候,会先在缓存池找到字符串相同的对象,然后指向缓存池中该对象,这样就避免了重新为该对象分配内存,从而提高了复用,所以建议多用直接量去创建对象,这个也是上篇博文所推荐的。 - 调用构造器创建对象
这种方法调用构造器,凡是new出来的对象都要进行内存分配,所以是不会指向缓存池之前已有的对象,这样就导致缓存池里面可能有多个值相同的String对象。
package biaodashi; /** * 字符串关于缓存池 * * @author ccf * */ public class StringHuanCunChi { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub StringHuanCunChi huanCunChi = new StringHuanCunChi(); huanCunChi.test1(); } public void test1() { String str1 = "ccf"; String str2 = "ccf"; String str3 = new String("ccc"); // new 会有新的地址分配,所以不会指向缓存池的"ccc" String str4 = new String("ccc"); System.out.println("str1==str2?" + (str1 == str2)); System.out.println("str3==str4?" + (str3 == str4)); } } 运行结果 str1==str2?true str3==str4?false
结果:看出str1 和str2都是指向同一个对象 而str3和str4就不是同一个对象了。
怎么样才能指向缓存池已有的对象:
要指向缓存池对象,改对象必须是直接赋直接量,也可以是多个直接量的运算值,而不能调用方法或者其他变量,但是被final修饰的可以进行宏替换的常量也可以看成直接赋值,因为以上这一些都能在加在类的时候,就被虚拟机计算出来其值。所以能指向缓存池。
public void test1() { String str1 = "ccf"; String str2 = "c" + "c" + "f";//三个直接量进行运算 System.out.println("str1==str2?" + (str1 == str2)); 结果:str1==str2?true 多个直接量进行连接,也可以指向缓存池
上面的代码中 String str2 = "c" + "c" + "f";一共创建了几个对象?????
可能有人会说n个,但是其实只有一个,因为虚拟机对他们进行直接的计算,不需要创建对象,这也是使用直接量的好处。
public void test1() { String str1 = "ccf" + "长度为:" + "3"; String str2 = "ccf" + "长度为:" + str1.length(); System.out.println("str1==str2?" + (str1 == str2)); // 结果: str1==str2?false 结论:str2调用了方法str1.length(),故不能再虚拟机加在类的时候就计算确定str的值,所以打印结果如下 } public void test1() { final String length1 = "3"; String length2 = "3"; String str1 = "ccf" + "长度为:" + "3"; String str2 = "ccf" + "长度为:" + length1;//调用final变量 String str3 = "ccf" + "长度为:" + length2;//调用普通变量 System.out.println("str1==str2?" + (str1 == str2)); System.out.println("str1==str3?" + (str1 == str3)); 结果: str1==str2?true str1==str3?false 可以得出结论:被final修饰的 length1效果是和直接量一样的,在虚拟机加在时候,length1是直接替换"3",之后就跟length1没关系了,效果可以说跟str1中一摸一样,这也是final变量和其他变量的不同之处,称为宏替换。
关于String的不可变问题:
String
String
} 类是个不可变的类,创建对象后,不可以改变对象,但是日常代码经常对String进行操作,这对于String不可变这一说法是不是相悖了?看下这段代码:
public void testString() { String str1 = "Hello"; int OldId = System.identityHashCode(str1); str1 = str1 + " ccf!";//对字符串进行操作 int NewId = System.identityHashCode(str1); System.out.println("OldId=" + OldId + "\nNewId=" + NewId); } 结果: OldId=854453928 NewId=584020407 其中System.identityHashCode(str1);函数是打印出对象的HashCode,每个对象都有一个唯一的HashCode ,是对象的唯一标识,很明显,前后两个HashCode是不同的,
得出一些结论:对String对象进行操作后,其返回的是一个新的对象,之前那个对象是没有改变的,改变的是str这个引用所指的对象,这时候的对象已经是新的对象,然而之前那个对象被废弃了,但是他存在缓存池,因此不会被垃圾回收机制回收,所以这里会出现内存泄漏,所以操作字符串,尽量不用String。
但是StringBuffer和StringBuilder进行字符串操作的时候,就不会去new出现对象,引用的都是同一个对象,就可以减少String带来的弊端。
public void testStringBuilder() { StringBuilder builder = new StringBuilder("Hello"); System.out.println("ID=" + System.identityHashCode(builder)); builder.append(" ccf!"); System.out.println("ID=" + System.identityHashCode(builder)); System.out.println(builder); } 结果: ID=854453928 ID=854453928 Hello ccf!
相关推荐
String,StringBuffer,StringBuilder区别。几乎所有的应用开发都离不开操作字符串,理解字符串的设计和实现以及相关 工具如拼接类的使用,对写出高质量代码是非常有帮助的
String StringBuffer和StringBuilder 区别之源码解析 从源码角度简单对它们之间的区别进行了验证
String ,StringBuffer与StringBuilder的区别
String:字符串常量 StringBuffer:字符创变量 StringBuilder:字符创变量 从上面的名字可以看到,String是“字符创常量”,也就是不可改变的对象。对于这句话的理解你可能会产生这样一个疑问 ,比如这段...
简单的介绍了String、StringBuffer和StringBuilder的区别
String及StringBuffer和StringBuilder的区别
介绍了String、StringBuffer、StringBuilder的使用方法,以及理论知识
String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别 String、StringBuilder和StringBuffer的区别
String、StringBuffer 和 StringBuilder 的区别 碎碎念 简单认识这三个对象 String StringBuffer StringBuilder 深入理解 String、StringBuilder、StringBuffer 从设计角度理解 String StringBuilder StringBuffer ...
string,stringbuffer,stringbuilder
Java中String,StringBuffer与StringBuilder的区别和用法。
Java 中操作字符串都有哪些类?它们之间有什么区别? 操作字符串的类有:String、StringBuffer、StringBuilder。 String 和 StringBuffer、StringBuilder 的区别在于 String 声明的是不可变的对象,每次操作都会...
string,stringBuffer,stringBuilder
JAVA平台提供了两个类:String和StringBuffer,它们可以储存和操作字符串,即包含多个字符的字符数据.这个String类提供了数值不可改变的字符串.而这个StringBuffer类提供的字符串进行修改.当你知道字符数据要改变的时候...
字符串String;Strings are Imm;字符串对象的创建方法;Interned String;Interned String;Interned String;取得字符串的长度;按照位置取得指定字符;遍历字符串;练习;下标越界异常;获取子字符串;获取子字符串;练习;查找...
java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间有什么区别呢?下面小编给大家总结了Java中String、StringBuffer、StringBuilder的区别详解,需要的朋友参考下吧
对于很多Java行业的菜鸟来说,弄清楚String;StringBuffer;StringBuilder三者之间的区别是很有必要的,很多面试面试官都会问到这个知识点。集合网络上很多牛人的各种经典分析的总结,花了两个小时概括总结得出了现在...
Java中的StringBuffer和StringBuilder类是用于处理字符串的可变对象; 它们与String类类似,但是不同之处在于,StringBuffer和StringBuilder可以修改字符串内容,而String对象是不可变的; StringBuffer和...
java JAVA数组与字符串,编写图形界面的程序,接收用户输入的一个字符串和一个字符,将字符串中出现的所有该字符删除,打印新生成的字符串。 String 类或StringBuffer类 deleteCharAt方法
java字符串操作大全,适合初学者,浅显易懂 部JAVA字符串操作 2008-07-11 15:39:42| 分类: JAVA | 标签: |字号大中小 订阅 . JAVA字符串的方法 String a = "53c015"; //Integer.parseInt(s, radix) radix设置为...