您的位置:首页 > 编程语言 > Java开发

java中String类总结(更新中)

2017-11-28 11:50 211 查看
因为入门时学的是C语言,在自学java时,发现java的String和c中着极大的差别,当时半知半解,现在重新整理下这方面知识点.

1. String和int/double等不同点之一是:String是不可变类。

一旦创建了 String 对象,那它的值就无法改变了

如果我们队String对象进行如下操作:

String a="asd";

System.out.println(a);

a="qwe"; 

System.out.println(a);

两次打印结果不同,但是事实上a只是指向堆内存中的引用,存储的是对象在堆中的地址,而非对象本身,a本身存储在栈内存中。

一种比较简单的识别方法是打印查看两个a的hashcode值:

String a="asd";
System.out.println(a);
System.out.println("a.hashcode="+a.hashCode());
a="qwe"; 
System.out.println(a);
System.out.println("a.hashcode="+a.hashCode());
String c="asd";
System.out.println("c.hashcode="+c.hashCode());

输出结果:

asd

a.hashcode=96882

qwe

a.hashcode=112383

c.hashcode=96882

这里显示两次打印的a的hashcode值不同,这说明两个a指向的并不是同一个对象,但是c和第一个打印的a的hashcode值相同。

需要注意的是String对Object中的hashcode进行了重写,具体如下:

 public int hashCode() {

      int h = hash;

      if (h == 0 && value.length > 0) {

          char val[] = value;

  

          for (int i = 0; i < value.length; i++) {

              h = 31 * h + val[i];

         }

          hash = h;

     }

     return h;

}

在String类中有个私有实例字段hash表示该串的哈希值,在第一次调用hashCode方法时,字符串的哈希值被计算并且赋值给hash字段,之后再调用hashCode方法便可以直接取hash字段返回。

在这里:

两个对象相等则它们的hashCode值必然相等; 

两个hashCode值相等的对象不一定相等;

2. String常用的两种创建方法如下:

String asd=new String(“haha”);

String zxc=“haha”;

这两种方法之间有着一定的区别

使用new方法的时候,会在堆内存申请一块内存存储字符串“haha”,asd指向其内存块对象。同时还会检查字符串常量池中是否含有“haha”<
4000
/span>字符串,若没有则添加“haha”到字符串常量池中。所以 new String()可能会创建两个对象。

但是在第二种情况中, 先检查字符串常量池中是否含有“haha”字符串,如果有则直接指向, 没有则在字符串常量池添加“haha”字符串并指向它.所以这种方法最多创建一个对象,有可能不创建对象。可以结合1中的例子。

3. String中使用加号拼接字符串

String中使用 + 字符串连接符进行字符串连接时,连接操作最开始时如果都是字符串常量,编译后将尽可能多的直接将字符串常量连接起来,形成新的字符串常量参与后续连接(通过反编译工具jd-gui也可以方便的直接看出);
接下来的字符串连接是从左向右依次进行,对于不同的字符串,首先以最左边的字符串为参数创建StringBuilder对象,然后依次对右边进行append操作,最后将StringBuilder对象通过toString()方法转换成String对象(注意:中间的多个字符串常量不会自动拼接)。

也就是说:

String k = "n1" + "n2 " + i + "n3" + "n4" + j; 实质上的实现过程是: 

String k = new StringBuilder("n1n2").append(i).append("n3").append("n4").append(j).toString();

当使用+进行多个字符串连接时,实际上是产生了一个StringBuilder对象和一个String对象。

在比较简单的额字符串连接中“+”和直接使用StringBuilder的差别不大,但是在比较复杂的情况下,“+”可能会产生更多的StringBuilder对象,例如:

 public class TestComplexPlus

  {

      public static void main(String[] args)

      {

          String s = "";

          Random rand = new Random();

          for (int i = 0; i < 10; i++)

          {

              s = s + rand.nextInt(1000) + " ";

          }

          System.out.println(s);

      }

  }

for循环处相当于:

for(int i = 0; i < 10; i++){

s = (new StringBuilder(String.valueOf(s))).append(rand.nextInt(1000)).append(" ").toString();

}

在这种情况中,每次for循环执行字符串拼接都会产生一个StringBuilder对象,不断产生垃圾,占用资源过多。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  string java