一、String类

1、定义

  • 字符串广泛应用 在 Java 编程中,在 Java 中字符串属于对象,Java 提供了 String 类创建操作字符串。

2、创建

  • 创建String字符串的方法两种。无论哪种方法创建的字符串都是不可以改变的
  • 一般基本数据类型存放在栈中,对象类型存放在堆中。在 Java 中字符串属于对象。

方法一:

String s = "fanjingchen";

java怎么定义string数组的例子 java定义string类型_StringBuilder类

  • 这种方法创建字符串后会有一个字符串池来保存内容,而栈空间存的是这个字符串的地址。这种方法创建的字符串在作为函数参数时是值传递。

方法二:

String s = new String("fanjingchen");

java怎么定义string数组的例子 java定义string类型_java怎么定义string数组的例子_02

  • 这种方法在创建字符串对象的同时,还会在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】初次学习若有不正之处请见谅,欢迎留言批评指正。