社区
Java SE
帖子详情
字符串与String
yqj2065
2009-01-07 03:43:09
太多关于String的问题了,
窃以为关键在于字符串(string,字符组成的串)和java.lang.String的关系一些模糊。
咱们讨论一下,它们是什么关系呢?(abstract)
...全文
168
9
打赏
收藏
字符串与String
太多关于String的问题了, 窃以为关键在于字符串(string,字符组成的串)和java.lang.String的关系一些模糊。 咱们讨论一下,它们是什么关系呢?(abstract)
复制链接
扫一扫
分享
转发到动态
举报
写回复
配置赞助广告
用AI写文章
9 条
回复
切换为时间正序
请发表友善的回复…
发表回复
打赏红包
yqj2065
2009-01-07
打赏
举报
回复
[Quote=引用 7 楼 jiangnaisong 的回复:]
常量池中的字符串的文字量 与 java.lang.String类的一个对象 是什么关系?是一回事吗?
不是!
[/Quote]
这就是关键。
大量的String的困惑来源于此。
********************
8楼的“ 4. String.intern(): ”中有误。
liuhua19841201
2009-01-07
打赏
举报
回复
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是可改变的。
云上飞翔
2009-01-07
打赏
举报
回复
[Quote=引用 2 楼 bigbro001 的回复:]
感觉String对象问题研究太深入了,就好比练蛤蟆功,会让人走火入魔,一般developer想要成为高手,还是练些内功(设计模式)比较好
[/Quote]
答:内功很重要.
若有时间的话
,研究String对象也会对低层概念多些了解.
楼主:"字符串(string,字符组成的串)和java.lang.String的关系一些模糊。"
1)"汉字abc" 这是一个字符串的文字量(或:字面量,即:字符组成的序列),
编译时
放在class中的常量池部分.
2)java.lang.String类的一个
对象
,
代表的
是一个字符串(值不可更改).
那么:常量池中的
字符串的文字量
与 java.lang.
String类的一个对象
是
什么关系
?是
一回事吗
?
不是!
在class装入内存是,
通常的
过程是:经过(
验证
,
准备
,
解析
)三个阶段,在解析阶段,会对 指向 常量池中的
字符串的文字量
的符号
引用
解析成
真正的
java.lang.
String类的一个对象的引用
.
且
保证
:所有指向常量池中的同一个字符串的文字量的符号引用,都会解析成:指向同一个真正的 java.lang.
String类的一个对象
.
renmms
2009-01-07
打赏
举报
回复
[Quote=引用 2 楼 bigbro001 的回复:]
感觉String对象问题研究太深入了,就好比练蛤蟆功,会让人走火入魔,一般developer想要成为高手,还是练些内功(设计模式)比较好
[/Quote]
蛤蟆功比如的好!
经典的API:
String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例来实现
flush_520
2009-01-07
打赏
举报
回复
[Quote=引用 1 楼 rumlee 的回复:]
java里面没有string,只有java.lang.String,字符串就是用java.lang.String来表示。
[/Quote]
因为是缺省的包 所以没看到导入
bzwm
2009-01-07
打赏
举报
回复
String是对象,String 用 char[] 存储字符。
String 很强大就是啦。
捏造的信仰
2009-01-07
打赏
举报
回复
对 String 的讨论主要是出于性能问题。了解一下 String、StringBuffer 和 StringBuilder 就可以了。
bigbro001
2009-01-07
打赏
举报
回复
感觉String对象问题研究太深入了,就好比练蛤蟆功,会让人走火入魔,一般developer想要成为高手,还是练些内功(设计模式)比较好
rumlee
2009-01-07
打赏
举报
回复
java里面没有string,只有java.lang.String,字符串就是用java.lang.String来表示。
java六大必须理解的问题 文档
java六大必须理解的问题、内容比较详细、写的比较具体
Python基本数据结构——
字符串
(
String
)
字符串
是不可变的,创建新
字符串
时不会修改原有
字符串
,这一点在处理文本数据时非常重要。在上述例子中,first_char获取的是
字符串
的第一个字符,last_char获取的是最后一个字符,而sub
string
则是从索引1到3的字符(不包括索引4)。在这个例子中,我们将
string
_a和
string
_b用空格连接在一起,形成了新的
字符串
combined_
string
。在Python中,
字符串
是不可变的。在Python中,可以使用单引号(')、双引号(")或三引号(''' 或 """)来创建
字符串
。
String
类--创建
字符串
以及
字符串
的相关操作
String
类的介绍
String
类是
字符串
操作类,
String
对象由0或多个包含在""下的字符组成,Java中把
String
类用final声明即创建后就不可修改。 创建
字符串
方式一:直接赋值
String
str = "abc"; 方式二:通过构造方法产生对象
String
str1 = new
String
("abc"); 方式三:通过字符数组产生对象 char[] data = new char[]{'a','b','c'};
String
str2 = new Stri
String
字符串
常量池
java.lang.
String
类的使用 1.概述
String
:
字符串
,使用一对""引起来表示。 1.
String
声明为final的,不可被继承 2.
String
实现了Serializable接口:表示
字符串
是支持序列化的。 实现了Comparable接口:表示
String
可以比较大小 3.
String
内部定义了final char[] value用于存储
字符串
数据 4.通过字面量的方式(区别于new给一个
字符串
赋值,此时的
字符串
值声明在
字符串
常量池中)。 5.
字符串
常量池中是不会存储相同内容(使用Str
判断一个
字符串
String
里是否包含另一个
字符串
判断一个
字符串
String
里是否包含另一个
字符串
Java SE
62,623
社区成员
307,257
社区内容
发帖
与我相关
我的任务
Java SE
Java 2 Standard Edition
复制链接
扫一扫
分享
社区描述
Java 2 Standard Edition
社区管理员
加入社区
获取链接或二维码
近7日
近30日
至今
加载中
查看更多榜单
社区公告
暂无公告
试试用AI创作助手写篇文章吧
+ 用AI写文章