Java String的缓冲池详解
来源:互联网 发布:俄勒冈州立大学 知乎 编辑:程序博客网 时间:2024/05/21 11:29
下面根据代码具体解释一下各种String构造情况。
代码如下:
- public class TestConstructString {
- public staticvoid main(String args[])
- {
- String s1 = "a";
- String s2 = "b";
- String s3 = "ab";
- String s4 = "ab";
- System.out.println("s3==s4? "+ (s3==s4));
- String s5 = "a"+"b";
- System.out.println("s3==s5? "+ (s3==s5));
- String s6 = s1+s2;
- System.out.println("s3==s6? "+ (s3==s6));
- String s7 = new String("ab");
- System.out.println("s3==s7? "+ (s3==s7));
- final String s8 = "a" ;
- final String s9 ="b" ;
- String s10 = s8 + s9;
- System.out.println("s3==s10? "+ (s3==s10));
- }
- }
输出结果为:
- s3==s4? true
- s3==s5? true
- s3==s6? false
- s3==s7? false
- s3==s10? true
在解释之前先对String做个简单的先容。
百度百科:java中的字符串。 String类是不可变的,对String类的任何改变,都是返回一个新的String类对象。 String 对象是 System.Char 对象的有序集合,用于表示字符串。String 对象的值是该有序集合的内容,并且该值是不可变的。
特别留意:String类是不可变(final)的,对String类的任何改变,都是返回一个新的String类对象.这样的话把String类的引用传递给一个方法,该方法对String的任何改变,对原引用指向的对象没有任何影响,这一点和基本数据类型相似.
String池:String是不可改变的,为了进步效率Java引用了字符串池的概念,例如new String("abc");首先会在String池中创建一个对象“abc”由于有NEW的 存在所以会分配地址空间copyString池的内容。当出现的String对象在String池中不存在时即在String池中创建该对象。
s3与s4根据String的概念他们都指向了同一个缓冲池内的地址,所以结果为true
s3与s5由于相加的两个为常量所以编译器会把s5="a"+"b"优化为s5="ab"。所以结果也为true。
s3与s6由于是两个变量的相加所以编译器无法优化,s1+s2即等同于(new StringBuilder(String.valueOf(s1))).append(s2).toString(); 在运行时,会有新的String地址空间的分配,而不是指向缓冲池中的“ab”。所以结果false。
s3与s7,根据缓冲池的定义在new的时候实际会新分配地址空间,s7指向的是新分配的地址空间所以与缓冲池地址不同,所以为false
s3与s10,类似于s3与s5,由于是final类型编译器进行了优化所以相同。
创建字符串的方式很多,回纳起来有三类:
其一,使用new关键字创建字符串,比如String s1 = new String("abc");
其二,直接指定。比如String s2 = "abc";
其三,使用串联天生新的字符串。比如String s3 = "ab" + "c";
String对象的创建
String对象的创建也很讲究,关键是要明白其原理。
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,假如不存在,则在池中创建一个字符串s,否则,不在池中添加。
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
原理3:使用直接指定或者使用纯字符串串联来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但尽不会在堆栈区再往创建该String对象。
原理4:使用包含变量的表达式来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将留意力集中到String池上。当调用 intern 方法时,假如池已经包含一个即是此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
最后,有几点题目请大家留意:String a; 与String a=null在作为类变量时候是等价的,在局部变量则不同。null表示一个空引用,String a=null意思是在栈中声明了a,但是这个a没有指向任何地址。此时我们留意到String a 在栈中声明了a,但是也没有指向任何地址,但是java的语法检查假如在局部变量中,String a;是不能直接使用的,String a=null中的这个a可以直接使用。
总之:
- //情况一
- String s1 = "s"; // 创建了一个对象;
- //情况二
- s1 = new String("s");//创建了两个对象
- //情况三
- String s2 = new String("a" + s1);//创建了三个对象
- Java String的缓冲池详解
- java String 缓冲池
- java 字符串 String 的缓冲池
- java String 缓冲池概念的举例说明
- java 字符串缓冲池 String缓冲池
- java 字符串缓冲池 String缓冲池
- java 字符串缓冲池 String缓冲池
- java 字符串缓冲池 String缓冲池
- java 字符串缓冲池 String缓冲池
- java字符串缓冲池 string缓冲池
- java String 缓冲池概念的举例说明(面试题)
- Java核心之String缓冲
- Java的String详解
- 【Java的String详解】
- java的String详解
- Java中的字符串缓冲池——String pool
- java 字符串缓冲池 String缓冲池 == 和equals
- 缓冲池和String池
- jQuery源码-解除绑定事件函数unbind
- 关于学习的一些思考
- hibernate二级缓存报错could not instantiate RegionFactory [org.hibernate.cache.impl.bridge.RegionFactoryCac
- C# 利用QRCode生成二维码图片
- Nginx PHP 使用 limit_req,limit_conn 限制并发,外加白名单
- Java String的缓冲池详解
- 软件安全测试之系统安全测试
- Android Wear开发可能用到的Android通知栏监听(仅适用4.3及以上)
- 小知识
- ArrayList和LinkedList的操作时间的差异
- Java中throw和throws的区别
- quick-cocos2d-x实现scrollview
- 欢迎使用CSDN-markdown编辑器
- 我的第一个汇编程序,使用分步运行-t是学习理解程序的好方法