String:
是对象不是原始类型.
为不可变对象,一旦被创建,就不能修改它的值.
对于已经存在的String对象的修改都是重新创建一个新的对象,然后把新的值保存进去.
String 是final类,即不能被继承.
StringBuffer:
是一个可变对象,当对他进行修改的时候不会像String那样重新建立对象
它只能通过构造函数来建立,
StringBuffer sb = new StringBuffer();
note:不能通过付值符号对他进行付值.
sb = "welcome to here!";//error
对象被建立以后,在内存中就会分配内存空间,并初始保存一个null.向StringBuffer
中付值的时候可以通过它的append方法.
sb.append("hello");
字符串连接操作中StringBuffer的效率要比String高:
String str = new String("welcome to ");
str += "here";
的处理步骤实际上是通过建立一个StringBuffer,让侯调用append(),最后
再将StringBuffer toSting();
这样的话String的连接操作就比StringBuffer多出了一些附加操作,当然效率上要打折扣.
并且由于String 对象是不可变对象,每次操作Sting 都会重新建立新的对象来保存新的值.
这样原来的对象就没用了,就要被垃圾回收.这也是要影响性能的. |
- //A:下面两种操作有区别吗?
- String s1 = new String("hello");
- String s2 = "hello";
- //B:请写出结果:
- String s1 = new String("hello");
- String s2 = new String("hello");
-
- System.out.println(s1==s2);
- System.out.println(s1.equals(s2));
- String s3 = new String("hello");
- String s4 = "hello";
- System.out.println(s3==s4);
- System.out.println(s3.equals(s4));
- String s5 = "hello";
- String s6 = "hello";
- System.out.println(s5==s6);
- System.out.println(s5.equals(s6));
- //C:字符串的常量和变量问题
- String s1 = "helloworld";
- String s2 = "hello";
- String s3 = "world";
- System.out.println(s1==s2+s3);
- System.out.println(s1=="hello"+"world");
- //D:字符串作为参数传递问题:
- String s1 = "hello";
- String s2 = "world";
- change(s1,s2);
- System.out.println(s1);
- System.out.println(s2);
- //change功能如下:
- public static void change(String s1,String s2) {
- s1 += "java";
- s2 += "ee";
- }
复制代码 String String 类代表字符串。Java 程序中的所有字符串字面值(如 "abc" )都作为此类的实例实现。
字符串是常量;它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为 String 对象是不可变的,所以可以共享。例如:
String str = "abc"; 等效于:
char data[] = {'a', 'b', 'c'}; String str = new String(data); 下面给出了一些如何使用字符串的更多示例:
System.out.println("abc"); String cde = "cde"; System.out.println("abc" + cde); String c = "abc".substring(2,3); String d = cde.substring(1, 2);
那么String为什么是不可改变的呢?
因为在Java中几乎所有的地方都要用到各种各样的字符和字符串,假如我new了一个字符串ABC,说明是创建了一个,不可改变的好处就在于
在String串池中只要有这个 字符串就可以不用再继续分配空间创建一个,那样会很浪费JVM为数不多了内存空间啊
相对的,StringBuffer为String的这个特殊之处提供了补充
StringBuffer 线程安全的可变字符序列。一个类似于 String 的字符串缓冲区,但不能修改。虽然在任意时间点上它都包含某种特定的字符序列,但通过某些方法调用可以改变该序列的长度和内容。
可将字符串缓冲区安全地用于多个线程。可以在必要时对这些方法进行同步,因此任意特定实例上的所有操作就好像是以串行顺序发生的,该顺序与所涉及的每个线程进行的方法调用顺序一致。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符添加或插入到字符串缓冲区中。append 方法始终将这些字符添加到缓冲区的末端;而 insert 方法则在指定的点添加字符。
例如,如果 z 引用一个当前内容是“start”的字符串缓冲区对象,则此方法调用 z.append("le") 会使字符串缓冲区包含“startle”,而 z.insert(4, "le") 将更改字符串缓冲区,使之包含“starlet”。
每个字符串缓冲区都有一定的容量。只要字符串缓冲区所包含的字符序列的长度没有超出此容量,就无需分配新的内部缓冲区数组。如果内部缓冲区溢出,则此容量自动增大。从 JDK 5 开始,为该类补充了一个单个线程使用的等价类,即 StringBuilder。与该类相比,通常应该优先使用 StringBuilder 类,因为它支持所有相同的操作,但由于它不执行同步,所以速度更快。
所以每一个东西都有它的两面性,我们尽可以挑选他好的一面,方便的一面去用。
希望能帮助你解决问题,我们一起加油吧!
|