Java String类详解

java.lang.String;是字符串类型,关于String类,首先需要注意以下几点:

1.字符串一旦创建不可改变。“abc”字符串对象一旦创建,不可再变成“abcd”;

2.提升字符串的访问效率:在程序中使用了“缓存”技术。所以在Java中所有使用“双引号”

括起来的字符串都会在“字符串常量池”中创建一份。字符串常量池在方法区中被存储。

3.在程序执行过程中,如果程序用到某个字符串,例如"abc",那么程序会在字符串常量池

中新建一个“abc”字符串,如果找到就直接拿来用。(字符串常量池是一个缓冲区,为了提高访问字符串的效率)

 

public class StringTest01{
 public static void main(String[] args){
   //创建一个“abc”字符串对象,该对象的内存地址,让s1变量保存。
   //s1是一个引用,s1指向“abc”对象。
   String s1="abc";
   //可以让s1重新指向
   //但是"def"字符串本身不可变
   s1="def";
   String s2="hello";  //在字符串常量池中新建一个"hello"字符串对象,该对象不可变
   String s3="hello";  //从字符串常量池中直接拿来用
   System.out.println(s2==s3);  // true
   //判断字符串是否相等不能用==
   String s4=new String("abc");
   String s5=new String("abc");
   System.out.println(s4==s5);  //false
   //以下程序在执行结束之后,会在字符串常量池中创建三个字符串对象"aaa""bbb""aaabbb"
   String s6="aaa";
   String s7="bbb";
   String s8=s6+s7;
 }
}

 

上述代码中,首先创建一个“abc”字符串对象,并且该对象的内存地址,让s1变量保存,也就是说s1是一个引用,指向“abc”对象。s1="def";是将s1重新指向字符串"def",但是"def"字符串本身不可变。接着创建了一个新的字符串s2,String s2="hello";在字符串常量池中新建一个"hello"字符串对象,该对象不可变,接下来再创建"hello"字符串时发现字符串常量池中已经存在这个字符串了,就不需要再重新创建,直接拿过来就可以用,也就是刚开始讲的第三条,这样做可以提高访问字符串的效率。使用String的时候我们还应该注意:尽量不要做字符串频繁的拼接操作,如上面的String s8=s6+s7,因为字符串一旦创建不可改变,只要频繁拼接,就会在字符串常量池中创建大量的字符串对象,给垃圾回收带来问题。

 

接下来看看不同的方法创建字符串对象的区别。

1.String s1="abc";只会在字符串常量池中创建一个“abc”字符串对象;

2.String s2=new String("hello");会在字符串常量池中创建一个“hello”字符串对象,并且在堆中再创建一个字符串对象。

第二种方式比较浪费内存,常用的是第一种方式。好了,接下来做一道题吧,运用刚刚讲的知识判断以下程序创建了了几个对象?

 

public class StringTest03{
 public static void main(String[] args){
   String s1=new String("hello");
   String s2=new String("hello");
   
 }
}

 

答案是三个,不知道大家有没有做对?

String s1=new String("hello");

String s2=new String("hello");

new出两个字符串对象,所以在堆中有两个对象,因为在Java中所有使用“双引号”括起来的字符串都会在“字符串常量池”中创建一份,字符串常量池在方法区中被存储,所以方法区的字符串常量池中一个,堆中的两个加常量池中的一个,就是最后的答案。

 

最后再来看看关于字符串常用的构造方法。

 

/*
关于字符串常用构造方法
*/
public class StringTest05{
 public static void main(String[] args){
   //1.
   String s1="abc";
   //2.
   String s2=new String("abc");
   //3.
   byte[] bytes={97,98,99,100};
   String s3=new String(bytes);
   System.out.println(s3);   //abcd   String已经重写了Object中的toString方法
   //4.
   String s4=new String(bytes,1,2);   //1代表起始下标,2代表长度
   System.out.println(s4);   //bc
   //5.
   char[] c1={'我','是','中','国','人'};
   String s5=new String(c1);
   System.out.println(s5);   //我是中国人
   //6.
   String s6=new String(c1,2,2);
   System.out.println(s6);  //中国
   }
}

wx搜索“程序员考拉”,专注java领域,一个伴你成长的公众号!

你可能感兴趣的:(java)