文档章节

java中String类详解(享元模式思考)

o
 onedotdot
发布于 2017/08/28 21:58
字数 1289
阅读 3
收藏 0

1. 首先String不属于8种基本数据类型,String是一个对象。 
因为对象的默认值是null,所以String的默认值也是null;但它又是一种特殊的对象,有其它对象没有的一些特性。 
2. new String()和new String(“”)都是申明一个新的空字符串,是空串不是null; 
3. String str=”kvill”; 
String str=new String (“kvill”);的区别: 
在这里,我们不谈堆,也不谈栈,只先简单引入常量池这个简单的概念。 
常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。 
看例1: 

String s0=”kvill”; 

String s1=”kvill”; 

String s2=”kv” + “ill”; 

System.out.println( s0==s1 ); 

System.out.println( s0==s2 );

结果为:

true 

true


首先,我们要知结果为道Java会确保一个字符串常量只有一个拷贝。 
因为例子中的s0和s1中的”kvill”都是字符串常量,它们在编译期就被确定了,所以s0==s1为true;而”kv”和”ill”也都是字符串常量,当一个字符串由多个字符串常量连接而成时,它自己肯定也是字符串常量,所以s2也同样在编译期就被解析为一个字符串常量,所以s2也是常量池中”kvill”的一个引用。


所以我们得出s0==s1==s2;


用new String() 创建的字符串不是常量,不能在编译期就确定,所以new String() 创建的字符串不放入常量池中,它们有自己的地址空间。 

看例2:

String s0=”kvill”; 

String s1=new String(”kvill”); 

String s2=”kv” + new String(“ill”); 

System.out.println( s0==s1 ); 

System.out.println( s0==s2 ); 

System.out.println( s1==s2 );

结果为:

false 

false 

false

例2中s0还是常量池中”kvill”的应用,s1因为无法在编译期确定,所以是运行时创建的新对象”kvill”的引用,s2因为有后半部分new String(“ill”)所以也无法在编译期确定,所以也是一个新创建对象”kvill”的应用;明白了这些也就知道为何得出此结果了。 

4. String.intern(): 

再补充介绍一点:存在于.class文件中的常量池,在运行期被JVM装载,并且可以扩充。String的intern()方法就是扩充常量池的一个方法;当一个String实例str调用intern()方法时,Java查找常量池中是否有相同Unicode的字符串常量,如果有,则返回其的引用,如果没有,则在常量池中增加一个Unicode等于str的字符串并返回它的引用;看例3就清楚了 

例3:

String s0= “kvill”; 

String s1=new String(”kvill”); 

String s2=new String(“kvill”); 

System.out.println( s0==s1 ); 

System.out.println( “**********” ); 

s1.intern(); 

s2=s2.intern(); //把常量池中“kvill”的引用赋给s2 

System.out.println( s0==s1); 

System.out.println( s0==s1.intern() ); 

System.out.println( s0==s2 );



结果为:

false 

********** 

false //虽然执行了s1.intern(),但它的返回值没有赋给s1 

true //说明s1.intern()返回的是常量池中”kvill”的引用 

true



最后我再破除一个错误的理解: 

有人说,“使用String.intern()方法则可以将一个String类的保存到一个全局String表中,如果具有相同值的Unicode字符串已经在这个表中,那么该方法返回表中已有字符串的地址,如果在表中没有相同值的字符串,则将自己的地址注册到表中“如果我把他说的这个全局的String表理解为常量池的话,他的最后一句话,“如果在表中没有相同值的字符串,则将自己的地址注册到表中”是错的: 

看例4:

String s1=new String("kvill"); 

String s2=s1.intern(); 

System.out.println( s1==s1.intern() ); 

System.out.println( s1+" "+s2 ); 

System.out.println( s2==s1.intern() );



结果:

false 

kvill kvill 

true



在这个类中我们没有声名一个”kvill”常量,所以常量池中一开始是没有”kvill”的,当我们调用s1.intern()后就在常量池中新添加了一个”kvill”常量,原来的不在常量池中的”kvill”仍然存在,也就不是“将自己的地址注册到常量池中”了。 

s1==s1.intern()为false说明原来的“kvill”仍然存在; 

s2现在为常量池中“kvill”的地址,所以有s2==s1.intern()为true。 

5. 关于equals()和==: 

这个对于String简单来说就是比较两字符串的Unicode序列是否相当,如果相等返回true;而==是比较两字符串的地址是否相同,也就是是否是同一个字符串的引用。 

6. 关于String是不可变的

这一说又要说很多,大家只要知道String的实例一旦生成就不会再改变了,比如说:String str=”kv”+”ill”+” “+”ans”; 

就是有4个字符串常量,首先”kv”和”ill”生成了”kvill”存在内存中,然后”kvill”又和” “ 生成 ”kvill “存在内存中,最后又和生成了”kvill ans”;并把这个字符串的地址赋给了str,就是因为String的“不可变”产生了很多临时变量,这也就是为什么建议用StringBuffer的原因了,因为StringBuffer是可改变的。

本文转载自:http://blog.csdn.net/huangbiao86/article/details/6384269

共有 人打赏支持
o
粉丝 7
博文 350
码字总数 14350
作品 0
朝阳
不变(Immutable)模式

一个对象的状态在对象被创建后就不再变化,这就是所谓的不变(Immutable)模式。 一般来说,一个对象要么是可变(Mutable Object)对象,要么是不可(Immutable Object)变对象。一个可变对象...

叶知秋
2013/07/02
0
0
享元(Flyweight Pattern)模式

Flyweight在拳击比赛中指最轻量级,选择使用“享元模式”的意译,是因为这样更能反映模式的用意。 享元模式的用意 享元模式对象的结构模式。享元模式以共享的方式高效地支持大量的细粒度对象...

叶知秋
2013/07/01
0
0
Java之美[从菜鸟到高手演变]之设计模式二

我们接着讨论设计模式,上篇文章我讲完了5种创建型模式,这章开始,我将讲下7种结构型模式:适配器模式、装饰模式、代理模式、外观模式、桥接模式、组合模式、享元模式。其中对象的适配器模式...

只想一个人静一静
2014/02/25
0
0
Android--面试中遇到的问题总结(三)

《Android 开发工程师面试指南 LearningNotes 》,作者是陶程,由梁观全贡献部分。大家可以去知乎关注这两位用心的少年。这份指南包含了大部分Android开发的基础、进阶知识,不仅可以帮助准备...

sealin
2017/02/22
0
0
享元(Flyweight)设计模式

1、享元模式以共享的方式高效地支持大量的细粒度对象 2、Java中的String类型就是使用了享元模式 String对象是final类型,对象一旦创建就不可改变 JAVA会确保一个字符串常量在常量池中只有一个...

职业搬砖20年
06/27
0
0

没有更多内容

加载失败,请刷新页面

加载更多

各种开源汇编、反汇编引擎的非专业比较

由于平时业余兴趣和工作需要,研究过并使用过时下流行的各种开源的x86/64汇编和反汇编引擎。如果要对汇编指令进行分析和操作,要么自己研究Intel指令集写一个,要么就用现成的开源引擎。自己...

simpower
11分钟前
1
0
(4)添加vue-router

(4)添加vue-router 1 安装vue-router cnpm install vue-router --save 2 页面准备 新建目录/src/views/common,此目录下面建立4个组件404.vue、home.vue、login.vue、theme.vue。每个文件...

neumeng
13分钟前
1
0
高可用性系统在大众点评的实践与经验

背景 所谓高可用性指的是系统如何保证比较高的服务可用率,在出现故障时如何应对,包括及时发现、故障转移、尽快从故障中恢复等等。本文主要以点评的交易系统的演进为主来描述如何做到高可用...

Skqing
21分钟前
2
0
Network protocols

The network stack does serveral seemingly-impossible things. It does reliable transmission over our unreliable networks, usually without any detactable hiccups. It adapts smooth......

nao
22分钟前
1
0
Android 生命周期方法

1,onCreate(); 2,onStart(); 3,onResume(); //打开页面,前三个方法自动执行 4,onPause(); 5,onStop(); //打开其他页面,前一个页面执行这俩方法 6,onRestart(); //onStart(),onResume //当关闭...

lanyu96
29分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部