一、String类介绍 点击此处返回总目录 二、String类的构造方法 三、String类的常用方法 四、String类练习 五、StringBuffer类 六、StringBuffer类的构造方法 七、StringBuffer类的常用方法 八、StringBuffer类练习 九、StringBuilder类 一、String类介绍 Java当中所有的字符串(用双引号引起来的)都是String类的对象。在Java中,一切都是对象,类是用来描述的对象的。字符串也是对象,String类就是描述字符串对象的。 注意:1 字符串对象的声明: String str = "liupc"; //String类不用写new,因为这样简单。也可以写成String str = new String("liupc");。 //其中:String是类;str是引用类型变量;"liupc"是类的对象。 String str = new String("liupc"); //使用这种方式时,会在堆上创建两个对象。【例2】 2 字符串是常量,他们的值在创建之后不能再更改。字符串的本质是一个字符数组。【例1】 例1:字符串是常量
package cn.itcast.demo01; public class Stringdemo {
public static void main(String[] args) {
String str = "liupc"; str = "aaa"; System.out.println(str); //aaa。str是引用类型变量,他是可以再指向另一个字符串的。字符串是常量是指"liupc"不能改变。 字符串本身是一个对象。"liupc"是一个对象,他是不能改变的。变量的指向变了。 } } |
为什么字符串是常量?我们看一下String类的实现:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
/** The value is used for character storage. */ private final char value[]; //可以看到字符串的本质是一个一维数组,而且是final的。一旦建立,就不变了。 /** Cache the hash code for the string */ private int hash; // Default to 0 ...... } |
例1的内存解释: 步骤一:main()方法入栈。 步骤二:堆里面有个小的区域叫常量池。里面存放了a,b,c....,z,A,B,C,..Z。当执行String str = "liupc"时,首先在堆上从常量池中拿出字 符来用,创建一个字符数组,为{'l','i','u','p','c'}。 步骤三:栈上创建str,指向刚才的字符数组。 步骤四:当指向str="aaa";时,重新创建一个字符数组{'a','a','a'}(不是把{'l','i','u','p','c'}改成{'a','a','a'},而是重新创建)。 步骤五:str指向这个数组。 例2:String str = new String("liupc"); 与String str = "liupc";的不同。
package cn.itcast.demo02; public class Stringdemo {
public static void main(String[] args) {
String str1 = "aaa"; String str2 = new String("aaa"); System.out.println(str1 == str2); //false。不同的对象。解释见下面的内存分析。 System.out.println(str1.equals(str2)); //true。比较的是字符串本身。 String str3 = "ccc"; String str4 = "ccc"; System.out.println(str3 == str4); //true。同一个对象。 System.out.println(str3.equals(str4)); //true。比较的是字符串本身。 String str5 = new String("ddd"); String str6 = new String("ddd"); System.out.println(str5 == str6); //false。不同的对象。解释见下面的内存分析。 System.out.println(str5.equals(str6)); //true。比较的是字符串本身。 } } |
例2的内存分析: ![](https://i-blog.csdnimg.cn/blog_migrate/c52a366afa60fcf88b2b7fa1bdab7877.png) 如上图,左边的例子,当执行String str1 = new String("abc")时,实际上在内存中创建了两个对象。首先"abc"是一个对象,其次new String()又是一个对象。new String()对象中存放的是"abc"对象的地址。然后str1指向new String()对象。 当执行 String str2 = "abc"时,运行时期,虚拟机做了优化,发现内存中有"abc",因此str2指向了之前的对象"abc"。 当执行System.out.println(str1 == str2);时,比较的是两个对象的地址,不同,为false。 当执行System.out.println(str1.equals(str2));时,因为String()类对Object类的equals()方法做了重写,所以比较的是字符串。相同为true。 例3:null和""
package cn.itcast.demo07; public class Test {
public static void main(String[] args) {
String s1 = null; String s2 = ""; String s3 = ""; //虚拟机做了优化,前面有"",所以s3也指向了同一个"" System.out.println(s1==null); //true //System.out.println(s1.equals(null)); //报空指针错误。【1】 System.out.println(s1==""); //false //System.out.println(s1.equals("")); //报空指针错误。【1】 //System.out.println(s1.length()==0); //报空指针错误。【1】 //System.out.println(s1.isEmpty()); //报空指针错误。【1】 System.out.println(s2.equals("")); //true。值比较。 System.out.println(s2==""); //true。比较的是两个对象的地址。s2也指向""。 System.out.println(s2.length()==0); //true System.out.println(s2.isEmpty()); //true System.out.println(s2.equals(s3)); //true。值比较。 System.out.println(s2==s3); //true。s2和s3指向同一个""。 String s = " liu li"; String[] st = s.split(" "); System.out.println(st[0]==""); //false.两个不同的对象。 System.out.println(st[0].equals("")); //true System.out.println(st[0].isEmpty()); //true System.out.println(st[0].length()==0); //true } } |
总结:判断一个字符串为空。 1. String s = null 。表示这个字符串不指向任何的东西,如果这时候调用String的方法,那么就会出现空指针异常。【1】 2. String s = "" 。表示s指向了一个长度为0的字符串。这时候就可以调用String的方法。 3. 判断一个字符串是不是为"",有三种方式:s.equals("")、s.isEmpty()、s.length==0。一般用第三种方式快。 所以写代码的时候拿到一个串,判断是否为空,标准写法是: if(s==null || s.length()==0) return false; 可以参考这篇文章: |