Java的String对象不能改变?
String是经常使用的一个类。是不是一旦初始化以后,就不可再更改了?有人说是因为:string:privatefinalcharvalue[];StringBuilde...
String是经常使用的一个类。是不是一旦初始化以后,就不可再更改了?
有人说是因为:
string:private final char value[];
StringBuilder:
public StringBuilder() {
super(2);
}
我是面试的时候给问到,String数据为什么不能修改,我该怎么回答好?? 展开
有人说是因为:
string:private final char value[];
StringBuilder:
public StringBuilder() {
super(2);
}
我是面试的时候给问到,String数据为什么不能修改,我该怎么回答好?? 展开
5个回答
2018-08-01 · 百度知道合伙人官方认证企业
育知同创教育
1【专注:Python+人工智能|Java大数据|HTML5培训】 2【免费提供名师直播课堂、公开课及视频教程】 3【地址:北京市昌平区三旗百汇物美大卖场2层,微信公众号:yuzhitc】
向TA提问
关注
展开全部
根据JDK中java.lang.String的源码进行分析,从中可以得出String类型的对象不可变的原因,大致上有如下两个:
1、java.lang.String类型在实现时,其内部成员变量全部使用final来修饰,保证成员变量的引用值只能通过构造函数来修改;
2、java.lang.String类型在实现时,在外部可能修改其内部存储值的函数实现中,返回时一律构造新的String对象或者新的byte数组或者char数组;
第2的重要性在于,假如通过String类型的toCharArray方法可以直接访问String类型内部定义的char数组,那么即便String类型内部的char数组使用了final来修饰,也仅仅保证这个成员变量的引用不可变,而无法保证引用指向的内存区域不可变。由上述两点,保证外部不可能修改java.lang.String类型对象的内部属性,从而保证String对象是不可变的。
提到String,就不得不提一下JDK中存在另外两个常用来表示字符串的类,StringBuffer和StringBuilder。根据注释,StringBuffer可谓老资格了,从JDK1.0时即伴随Java征战世界,而StringBuilder直到JDK1.5时才出现。
面试时,StringBuffer和StringBuilder的区别也是常问的话题,有些没有开发经验,对多线程编码不了解、对synchronized的使用不熟悉的兄弟,很容易在这个问题上吃亏。
StringBuffer和StringBuilder的共同点:
1、都是可变对象,对象内的字符缓存会随着拼接操作而动态扩展;
2、用来完成字符串拼接操作;
3、构造时传入内部缓存大小时,可以降低缓存扩展的次数,明显提升字符串拼接操作的效率;
StringBuffer和StringBuilder的区别:
1、StringBuilder的方法都是线程不安全的,从另外一个角度讲,StringBuilder类型的对象在做字符串拼接操作时,由于少了线程同步的操作,执行效率上有很大提升;
2、StringBuffer的方法都加上了synchronized关键字,因而在一定的场景下,StringBuffer类型的对象都是线程安全的,但在执行效率上,由于多了线程同步的操作,因而会有少许的损失;
在大多数场景下,字符串拼接操作都是不需要考虑多线程环境下对结果的影响的,因而使用StringBuilder类型可以提升代码的执行效率。
在多个线程的代码中共享同一个StringBuffer类型的对象时,需要关注synchronized关键字对最终结果的影响。由于StringBuffer类的实现中,仅仅对每个方法使用了synchronized修饰,这只能保证在多线程场景下,访问StringBuffer对象的同一个方法时可以保证最终结果的一致性,假如一个线程访问A方法,另外一个线程方法B方法,则由于加锁对象的不同,可能会出现不一致的现象,这是需要程序员特别要注意的地方。类似的,可以参考Vector的实现和应用场景。
1、java.lang.String类型在实现时,其内部成员变量全部使用final来修饰,保证成员变量的引用值只能通过构造函数来修改;
2、java.lang.String类型在实现时,在外部可能修改其内部存储值的函数实现中,返回时一律构造新的String对象或者新的byte数组或者char数组;
第2的重要性在于,假如通过String类型的toCharArray方法可以直接访问String类型内部定义的char数组,那么即便String类型内部的char数组使用了final来修饰,也仅仅保证这个成员变量的引用不可变,而无法保证引用指向的内存区域不可变。由上述两点,保证外部不可能修改java.lang.String类型对象的内部属性,从而保证String对象是不可变的。
提到String,就不得不提一下JDK中存在另外两个常用来表示字符串的类,StringBuffer和StringBuilder。根据注释,StringBuffer可谓老资格了,从JDK1.0时即伴随Java征战世界,而StringBuilder直到JDK1.5时才出现。
面试时,StringBuffer和StringBuilder的区别也是常问的话题,有些没有开发经验,对多线程编码不了解、对synchronized的使用不熟悉的兄弟,很容易在这个问题上吃亏。
StringBuffer和StringBuilder的共同点:
1、都是可变对象,对象内的字符缓存会随着拼接操作而动态扩展;
2、用来完成字符串拼接操作;
3、构造时传入内部缓存大小时,可以降低缓存扩展的次数,明显提升字符串拼接操作的效率;
StringBuffer和StringBuilder的区别:
1、StringBuilder的方法都是线程不安全的,从另外一个角度讲,StringBuilder类型的对象在做字符串拼接操作时,由于少了线程同步的操作,执行效率上有很大提升;
2、StringBuffer的方法都加上了synchronized关键字,因而在一定的场景下,StringBuffer类型的对象都是线程安全的,但在执行效率上,由于多了线程同步的操作,因而会有少许的损失;
在大多数场景下,字符串拼接操作都是不需要考虑多线程环境下对结果的影响的,因而使用StringBuilder类型可以提升代码的执行效率。
在多个线程的代码中共享同一个StringBuffer类型的对象时,需要关注synchronized关键字对最终结果的影响。由于StringBuffer类的实现中,仅仅对每个方法使用了synchronized修饰,这只能保证在多线程场景下,访问StringBuffer对象的同一个方法时可以保证最终结果的一致性,假如一个线程访问A方法,另外一个线程方法B方法,则由于加锁对象的不同,可能会出现不一致的现象,这是需要程序员特别要注意的地方。类似的,可以参考Vector的实现和应用场景。
本回答被网友采纳
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
2012-04-14 · 知道合伙人互联网行家
关注
展开全部
正解:
因为String类型的对象在创建完成后实际在内存中是存放于数据空间中(data segment),改变String类型引用指向新的字符串实际是改变了String对象的引用地址,而非实际的值。
比如:
String s = "abc";
s = "123";
内存中实际在data segment区域先初始化一个"abc"然后 将引用赋值给s这个string对象,第二句,是再在data segment区域初始化一个"123"然后将引用传递给s,实际上并不是直接将"abc"的值改为"123",这就是问题所说的string不能改变。
因为String类型的对象在创建完成后实际在内存中是存放于数据空间中(data segment),改变String类型引用指向新的字符串实际是改变了String对象的引用地址,而非实际的值。
比如:
String s = "abc";
s = "123";
内存中实际在data segment区域先初始化一个"abc"然后 将引用赋值给s这个string对象,第二句,是再在data segment区域初始化一个"123"然后将引用传递给s,实际上并不是直接将"abc"的值改为"123",这就是问题所说的string不能改变。
追问
回答得不错~谢谢~
不过第7行的回答:“内存中实际在.....”这段只是说明了String对象引用改变的原理,并没有说明“为什么不能改变”哦~
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
1.这是定义:public final class Stringextends Objectimplements Serializable, Comparable<String>, CharSequence
2.String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
3.字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
"String类提供了数值不可改变的字符串。"
请问你是怎么理解这句话的-------------------------开辟空间后仅仅可以填充一次
2.String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
3.字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc";
"String类提供了数值不可改变的字符串。"
请问你是怎么理解这句话的-------------------------开辟空间后仅仅可以填充一次
追问
开辟空间后仅仅可以填充一次
这也不一定。StringBuilder 可以通过一个 expandCapacity的方法进行扩充容量,修改。
追答
大姐,咱说的是string
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
展开全部
你编程时,可以随意改变,想改成什么,它就是什么.无须考虑java的内部处理机制.
在java内部处理时,你每改变一次,java实际是放弃以前的串,而重新产生一个空间,存储你重新产生的串.String可使编程方便,要效率高的话,应多使用StringBuffer
在java内部处理时,你每改变一次,java实际是放弃以前的串,而重新产生一个空间,存储你重新产生的串.String可使编程方便,要效率高的话,应多使用StringBuffer
追问
"String类提供了数值不可改变的字符串。"
请问你是怎么理解这句话的?
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询