一、String类
1、定义
- 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类来创建和操作字符串。
2、创建
- 创建String字符串的方法两种。无论哪种方法创建的字符串都是不可以改变的。
- 一般基本数据类型存放在栈中,对象类型存放在堆中。在 Java 中字符串属于对象。
方法一:
String s = "fanjingchen";
- 这种方法创建字符串后会有一个字符串池来保存内容,而栈空间存的是这个字符串的地址。这种方法创建的字符串在作为函数参数时是值传递。
方法二:
String s = new String("fanjingchen");
- 这种方法在创建字符串对象的同时,还会在String pool中创建一个对象。因此执行了上面语句后实际上创建了两个对象。
3、栗子
字符串不可变
package fjchr;
class FJC{
public static void main(String[] args) {
String s = "fanjingchen";
System.out.println("s="+s);
s="liutifeng";
System.out.println("s="+s);
}
}
- 运行结果为
s=fanjingchen
s=liutifeng
- 分析:
- 原因在于实例中的 s 只是一个 String 对象的引用,并不是对象本身,当执行 s = “liutifeng”; 创建了一个新的对象 “liutifeng”,而原来的 “fanjingchen” 还存在于内存中。
- 字符串实际上就是一个 char 数组,并且内部就是封装了一个 char 数组。这里 char 数组是被 final 修饰的。并且 String 中的所有的方法,都是对于 char 数组的改变,只要是对它的改变,方法内部都是返回一个新的 String 实例。
public final class String
implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */
private final char value[];
字符串的==与equals()
public class FJC {
public static void main(String[] args) {
String str1 = "hello world";
String str2 = new String("hello world");
String str3 = "hello world";
String str4 = new String("hello world");
System.out.println(str1==str2);
System.out.println(str1==str3);
System.out.println(str2==str4);
System.out.println(str1.equals(str2));
System.out.println(str1.equals(str3));
System.out.println(str2.equals(str4));
}
}
- 运行结果为
false
true
false
true
true
true
- 分析:
- String str1 = “hello world”; 和 String str3 = “hello world”; 都在编译期间生成了字面常量和符号引用,运行期间字面常量 “hello world” 被存储在运行时常量池(当然只保存了一份)。通过这种方式来将 String 对象跟引用绑定的话,JVM 执行引擎会先在运行时常量池查找是否存在相同的字面常量,如果存在,则直接将引用指向已经存在的字面常量;否则在运行时常量池开辟一个空间来存储该字面常量,并将引用指向该字面常量。
- 众所周知,通过 new 关键字来生成对象是在堆区进行的,而在堆区进行对象生成的过程是不会去检测该对象是否已经存在的。因此通过 new 来创建对象,创建出的一定是不同的对象,即使字符串的内容是相同的。
- 对于字符串常量池:当一个字符串是一个字面量时,它会被放到一个常量池中,等待复用。
二、StringBuffer 类
1、作用
- 当对字符串进行修改的时候,需要使用 StringBuffer类。
2、栗子
package fjchr;
class FJC{
public static void main(String[] args) {
StringBuffer s = new StringBuffer("fanjingchen");
System.out.println("s="+s);
s.append("是");
s.append("帅哥");
System.out.println("我承认"+s);
}
}
- 运行结果为
s=fanjingchen
我承认fanjingchen是帅哥
- 分析:
- StringBuffer 和 String 是有一定的区别的,首先,String 是被 final 修饰的,他的长度是不可变的,就算调用 String 的 concat 方法,那也是把字符串拼接起来并重新创建一个对象,把拼接后的 String 的值赋给新创建的对象,而 StringBuffer 的长度是可变的,调用StringBuffer 的 append 方法,来改变 StringBuffer 的长度,并且,相比较于 StringBuffer,String 一旦发生长度变化,是非常耗费内存的!
3、方法
- public StringBuffer append(String s),将指定的字符串追加到此字符序列。
- public StringBuffer reverse(),将此字符序列用其反转形式取代。
- public delete(int start, int end),移除此序列的子字符串中的字符。
- public insert(int offset, int i),将 int 参数的字符串表示形式插入此序列中。
- replace(int start, int end, String str),使用给定 String 中的字符替换此序列的子字符串中的字符。
三、String类、StringBuffer类和StringBuilder类的区别
- 和 String 类不同的是,StringBuffer 和 StringBuilder 类的对象能够被多次的修改,并且不产生新的未使用对象。
- StringBuilder 类在 Java 5 中被提出,它和 StringBuffer 之间的最大不同在于 StringBuilder 的方法不是线程安全的(不能同步访问)。
- 由于 StringBuilder 相较于 StringBuffer 有速度优势,所以多数情况下建议使用 StringBuilder 类。
- 然而在应用程序要求线程安全的情况下,则必须使用 StringBuffer 类。
- 可以使用toString()方法将StringBuilder和String进行转换。
总结
- String长度不可变,修改字符串必定创建新对象,其他两个长度可变,修改不会创建新对象。
- StringBuffer 线程安全 ,StringBuilder 线程不安全。
- StringBuilder 速度快,一般所有遇到的情况都用他。
【END】初次学习若有不正之处请见谅,欢迎留言批评指正。