首页 > 试题广场 >

String与StringBuffer的区别是?

[不定项选择题]
String与StringBuffer的区别是?
  • String是不可变的对象,StringBuffer是可以再编辑的
  • 字符串是常量,StringBuffer是变量
  • String是可变的对象,StringBuffer是不可以再编辑的
  • 以上说法都不正确
当说到 String 字符串时,必然会涉及到 “字符串常量池” 这个概念。
像 "abc" 这种直接用双引号括起来的字符串,我们称之为 “字符串字面量”,简称“字面量”。
JVM为了减少字符串对象的重复创建,会在方法区中维护了一段特殊的内存,这段内存被称为 字符串常量池 或者 字符串字面量池

理解 字符串常量池 的关键是:关注编译期的行为
我们将下面一段代码分成两个阶段来看:
String str1 = new String("abc");
String str2 = "a" + "b" +"c";

(1)编译期,编译 class 文件
在编译时,字符串的字面量 "abc" 就会与类、方法等信息一起被保存到 class 文件中,字面量会被保存到 class 文件中的静态常量池。
如果两个已知的字符串字面量直接用 “+” 号拼接,在编译期,这两个字符串字面量以及拼接之后的得到新字符串对编译器而言,都是明确可知的,那么编译器就会对这种代码进行优化,会将之保存到 class 文件的静态常量池中,便于后面运行时的复用,提高了效率。

(2)运行期,加载class文件
运行期会将 class 文件中的静态常量池中的常量,加载到运行时常量池(即字符串常量池)中,成为一个字符串对象。
接着 JVM 解释运行程序,当执行到以字面量形式创建字符串对象的代码时,JVM 首先会去字符串常量池(此时是运行时常量池)中进行检查,如果字符串常量池中存在相同内容的字符串对象,则将这个对象引用直接返回,否则在堆(Heap)中创建一个新的字符串对象,然后将新建对象的引用地址返回。

回到上述两行代码,分别看看创建了几个对象。
str1:创建了 2 个对象,字符串字面量会在字符串常量池中创建一个对象,new 关键字会在 Heap 中创建一个对象,两个对象的地址不一样。
str2:创建了 4 个对象,除了 "a"、"b"、"c" 三个字符串字面量以外,还会创建 "abc" 字符串字面量。

发表于 2018-02-24 12:39:22 回复(0)
更多回答
B(String是常量,StringBuffer是变量 )为什么错了?前半句错了还是后半句错了?
发表于 2016-08-05 15:53:20 回复(3)
B String 用于创建字符串常量, StringBuffer和StringBuilder(JDK 1.5 later)用于创建字符串变量
发表于 2015-04-09 18:06:05 回复(0)
A:String是用了final来修饰的,所以他是不可变的;而StringBuffer是可以动态添加元素的对象,它是String的补充
B:String不是常量,它是字符串常量;Stringbuffer不是变量,它是字符串变量。
C:请参考A;
发表于 2017-01-13 14:52:10 回复(1)
对于B选项,String是直接量,也就是说,String类型的字符串可以直接赋值给String引用变量,比如字符串"abc",可以直接赋值String Str = "abc",但是StringBuffer只能new一个对象之后再进行赋值操作,java敏感词有九个直接量:int,char,long,float,double,true,false,null,String,直接量可以直接赋值对应的类型。
发表于 2016-08-05 15:59:35 回复(0)
抖个机灵。多选题的话d一定错 c很明显错了 所以选ab
发表于 2021-08-06 18:32:56 回复(0)
它说的是“字符串是常量”,没有说“String是常量”,没理解题,是我错了🙃
发表于 2021-04-13 09:04:07 回复(0)
String类用final关键词修饰(final修饰的类不可被继承,方法不可被重写,变量不可变),所以,String类型的变量值一旦被创建便不可修改。StringBuffer和StringBuiled是可变的。
StringBuffer,默认加了同步锁,所以线程安全,适合多线程开发。而StringBuiled没有,所以是线程不安全的。
处理速度,StringBuilder > StringBuffer > String。少量数据用String,大量数据,单线程用StringBuilder。
编辑于 2019-07-19 09:35:19 回复(1)
开始以为String引用可变,所以没选字符串是常量,后查看jdk1.8文档:

Strings are constant; their values cannot be changed after they are created. String buffers support mutable strings. Because String objects are immutable they can be shared.

发表于 2018-04-07 10:33:36 回复(0)
这个题目的说法太不地道了,String是不可变类,怎么就成了对象了?
发表于 2016-03-25 20:03:59 回复(3)

String, StringBuffer,StringBuilder的区别

java中String、StringBuffer、StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题。现在总结一下,看看他们的不同与相同。

1.可变与不可变

String类中使用字符数组保存字符串,如下就是,因为有“final”修饰符,所以可以知道string对象是不可变的。

private final char value[];

      String 为不可变对象,一旦被创建,就不能修改它的值. . 对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.

StringBuilder与StringBuffer都继承自AbstractStringBuilder类,在AbstractStringBuilder中也是使用字符数组保存字符串,如下就是,可知这两种对象都是可变的。

char[] value;

     StringBuffer:是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象 , 它只能通过构造函数来建立,  如: StringBuffer sb = new StringBuffer();

不能通过赋值符号对他进行付值. sb = "welcome to here!";//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer中赋值的时候可以通过它的append方法.      sb.append("hello");

2.是否多线程安全

String中的对象是不可变的,也就可以理解为常量, 显然线程安全

AbstractStringBuilder是StringBuilder与StringBuffer的公共父类,定义了一些字符串的基本操作,如expandCapacity、append、insert、indexOf等公共方法。

StringBuffer对方法加了同步锁或者对调用的方法加了同步锁,所以是 线程安全的 。看如下源码:

 

1   public   synchronized  StringBuffer reverse() {

2       super .reverse();

3       return   this ;

4  }

5  

6   public   int  indexOf(String str) {

7       return  indexOf(str, 0);         //存在 public synchronized int indexOf(String str, int fromIndex) 方法

8  }

 

StringBuilder并没有对方法进行加同步锁,所以是 非线程安全的

 3.StringBuilder与StringBuffer共同点

StringBuilder与StringBuffer有公共父类AbstractStringBuilder( 抽象类 )。

抽象类与接口的其中一个区别是:抽象类中可以定义一些子类的公共方法,子类只需要增加新的功能,不需要重复写已经存在的方法;而接口中只是对方法的申明和常量的定义。

StringBuilder、StringBuffer的方法都会调用AbstractStringBuilder中的公共方法,如super.append(...)。只是StringBuffer会在方法上加synchronized关键字,进行同步。

最后,如果程序不是多线程的,那么使用StringBuilder效率高于StringBuffer。

 

效率比较String < StringBuffer < StringBuilder,但是在String S1 =“This is only a”+“simple”+“test”时,String效率最高。

发表于 2016-08-11 22:12:57 回复(23)
我觉得String是常量这句话表述有问题。字符串是常量没问题,但是String类型的引用它就是变量,这个引用的指向是可以变的。
发表于 2016-02-09 12:35:57 回复(15)
String 字符串常量 
StringBuffer 字符串变量(线程安全) 
StringBuilder 字符串变量(非线程安全)
String 类代表字符串。Java 程序中的所有字符串字面值(如 “abc” )都是String类的对象。字符串是常量;它们的值在创建之后不能改变。所以可以共享它们。StringBuffer是字符串缓存区,它的内容可以被修改,长度也可以改变,StringBuffer类是线程安全的,也就是说多个线程可以安全的访问StringBuffer对象。StringBuilder与StringBuffer类似,都是字符串缓冲区,但StringBuilder不是线程安全的,如果你只是在单线程中使用字符串缓冲区,那么StringBuilder的效率会更高些。值得注意的是StringBuilder是在JDK1.5版本中增加的。以前版本的JDK不能使用该类。
编辑于 2016-06-12 15:29:58 回复(7)
String 是不可变的,String变量一旦初始化后就不能更改,禁止改变对象的状态,从而增加共享对象的坚固性、减少对象访问的错误,同时还避免了在多线程共享时进行同步的需要 。那么,到底什么是不可变的对象呢? 可以这样认为: 如果一个对象,在它创建完成之后,不能再改变它的状态,那么这个对象就是不可变的。不能改变状态指的是不能改变对象内的成员变量,包括:
  • 基本数据类型的值不能改变;

  • 引用类型的变量不能指向其他的对象;

  • 引用类型指向的对象的状态也不能改变;

除此之外,还应具有以下特点:

  • 除了构造函数之外,不应该有其它任何函数(至少是任何public函数)修改任何成员变量;

  • 任何使成员变量获得新值的函数都应该将新的值保存在新的对象中,而保持原来的对象不被修改。


关于 Java String 类 的更详细的阐述,请查看我的博
客“http://blog.csdn.net/justloveyou_/article/details/52556427”。欢迎留言,欢迎指教!
发表于 2016-12-05 16:20:25 回复(0)
String是不可变类型,StringBuffer是可变类型
String可以进行常量赋值 String str="123";
也可以进行new运算操作创建对象。
StringBuffer只能通过new运算创建对象。
发表于 2015-11-07 21:46:35 回复(3)
作者:醉翁之意008
链接:https://www.zhihu.com/question/24973987/answer/339668534
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

区别一:在Java中字符串使用String类进行表示,但是String类表示字符串有一个最大的问题:“字符串常量一旦声明则不可改变,而字符串对象可以改变,但是改变的是其内存地址的指向。”所以String类不适合于频繁修改的字符串操作上,所以在这种情况下,往往可以使用StringBuffer类,即StringBuffer类方便用户进行内容修改,

区别二:在String类中使用“+”作为数据的连接操作,而在StringBuffer类中使用append()方法(方法定义:public StringBuffer append(数据类型 变量))进行数据连接。

区别三:两个类的定义结构不同

String类

public final class String extends Object implements Serializable, Comparable<String>, CharSequence

StringBuffer类

public final class StringBuffer extends Object implements Serializable,CharSequence

通过两个定义结构可以发现,String类和StringBuffer类都是CharSequence接口的子类,也就证明String类和StringBuffer类的对象都可以利用自动向上转型的操作为CharSequence接口实例化。

区别四:String类和StringBuffer类的转换。虽然String类和StringBuffer类都属于CharSequence接口的子类,但是这两个类对象是不能直接转换的。可以通过两种方法:

1.将String转换为StringBuffer类对象

方式一:利用StringBuffer类的构造方法(public StringBuffer(String str))。接收String类对象,可以将String类对象实例化为StringBuffer类对象。

方式二:利用StringBuffer类中的append()方法(public StringBuffer append(String str))。利用append()方法像StringBuffer类中增加了一个String类对象,这样就相当于将String类对象转换为StringBuffer类对象。

2.将StringBuffer转换为String类对象

方式一:利用toString()方法可以将StringBuffer转换为String类对象

实际上所有的类都会继承Object类的toString方法,所以所有的类对象都可以转换为String类对象。

方法二:利用String类的构造方法(public String(StringBuffer buffer))实现StringBuffer类与String类的转换。

区别五:String类与StringBuffer类中定义的常用方法,两个类的大部分方法可以互补,String类应该很熟悉,我就说几个常用的StringBuffer类方法:

public StringBuffer append(数据类型 变量) ——普通方法——用于数据追加操作

public StringBuffer reverse() ——普通方法——用于字符串反转操作

public StringBuffer insert(int offset,数据类型 变量)——普通方法——在指定位置追加内容

发现以上方法都返回StringBuffer类对象,所以可以使用代码链的方式一直调用StringBuffer类的方法,例如:对象.append().insert()....。

区别六:遇到字符串处理优先考虑使用String。在实际开发中只有频繁修改内容才考虑使用StringBuffer类或StringBuilder类操作。

从JDK1.5开始,Java增加了一个新的字符串操作类:StringBuilder类。这个类的定义结构如下:

public final class StringBuilder extends Object implements Serializable,CharSequence

通过定义结构发现,StringBuilder类和StringBuffer类是完全相同的,而且打开Java Doc文档后可以发现两个类的方法功能都是相同的。而打开Java源码你会发现区别,在StringBuffer类中定义的方法全部使用“synchronized”进行同步定义,属于安全的线程操作;而StringBuilder类没有同步定义,StringBuilder类的方法都是异步方法,属于非安全线程操作。

发表于 2019-12-09 23:06:09 回复(0)
B说的是String是常量,又不是字符串常量, 那每次new String()对象的话, 那作为对象他不就是个变量了?
发表于 2015-12-22 21:10:14 回复(0)
String类是不可变类,一旦一个String对象被创建以后,包含在这个对象中的字符序列是不可改变的,直至这个对象被销毁。 StringBuffer对象则代表一个字符序列可变的字符串,当一个StringBuffer被创建以后,通过StringBuffer提供的append()、insert()、reverse()、setCharAt()、setLength()等方法可以改变这个字符串对象的字符序列。一旦通过StringBuffer生成了最终想要的字符串,就可以调用它的toString()方法将其转换为一个String对象。 因此选项A、B正确。
发表于 2022-10-25 13:08:46 回复(0)
String,StringBuild,StringBuffer之间的区别
  1. String是字符串常量,一旦创建之后内存地址不在发生改变,当添加数据时内存地址发生改变;StringBuild和StringBuffer为字符串变量,添加数据时内存地址不会发生改变
  2. StringBuild和StringBuffer底层为数组,StringBuild从JDK1.5开始,StringBuffer从JDK1.0开始
  3. StringBuild线程安全,方法被synchronized修饰,效率低;StringBuffer线程不安全,效率高
发表于 2022-09-27 23:40:03 回复(0)
String不可变这句话有点问题,String是可以重新赋值的,因为本身就是个变量引用。
发表于 2021-07-09 10:29:08 回复(0)