关于String类

      一个看似很简单的问题:当String s = new String("kevin");后内存中有几个对象?

      通常回答分两类,一个对象和两个对象。有关两个对象的错误认识是s 和kevin。但是情况似乎并不是那样简单!我们做个测试。我们知道java中 == 比较的是对象的引用是不是相同,就是比较是不是指向同一个对对象,也就是比较是不是同一个对象。我们据此写一小段测试代码:

package com.ys.String;
public class StringTest {
 
 public static void main(String[] args) {
  String s0 = new String ("kevin");
  String s1 = "kevin";
  String s2 = new String ("kevin");
  String s3 = "kevin";
  
  if(s0 == s1 ){
   System.out.println("s0和s1指向相同的对象");
  } else {
   System.out.println("s0和s1指向不同的对象");
  }
  
  if(s1 == s2) {
   System.out.println("s2和s1指向相同的对象");
  } else {
   System.out.println("s2和s1指向不同的对象");
  }
  
  if(s0 == s2) {
   System.out.println("s2和s0指向相同的对象");
  } else {
   System.out.println("s2和s0指向不同的对象");
  }
  
  if(s3 == s1 ){
   System.out.println("s3和s1指向相同的对象");
  } else {
   System.out.println("s3和s1指向不同的对象");
  }
 
  System.out.println(s0 == s1); //false
  System.out.println(s1 == s2); //false
  System.out.println(s0 == s2); //false
  System.out.println(s1 == s3); //true
  
  System.out.println(s0.equals(s1)); //true
  System.out.println(s0.equals(s2)); //true
  System.out.println(s0.equals(s1)); //true
  System.out.println(s0.equals(s1)); //true
 }
}

      输出结果如下:

s0和s1指向不同的对象
s2和s1指向不同的对象
s2和s0指向不同的对象
s3和s1指向相同的对象
false
false
false
true
true
true
true
true

   由此我们可以得出结论:上面的s0 s1 s2他们指向了不同的对象,他们是不同的对象引用。而s1 s3是相同的对象引用。但是这仍然没有能够回答我们的问题,到底几个对象生成了?造成s0 s1 s2指向不同对象的原因何在?我们需要大概了解java中有关String的内存分配原理。

 

    当执行String s0 = new String("kevin")的时候,会为其创建一个字符串缓冲池(pool)。当创建一个字符串对象的时候其执行流程是这样的:首先他到pool中去寻找是否有一个叫内容为kevin的这样的一个对象存在。因为String s0 = new String("kevin")是main方法的第一条语句此时还没有pool中是没有对象的。此时他会把括号中的kevin对象放到pool中。接下来执行构造方法在堆(heap)中生成一个内容为kevin的对象。所以这样就造成了pool 和 heap中都有一个内容为kevin的对象。这样就解答了我们的问题。我们知道通过 String s0 = new String("kevin") 后,其实产生了两个对象。通过最后四行的代码我们也可以清楚的知道。就是说java中 == 比较的是对象的引用  equals()方法比较的是对象的内容是不是相同。

 

    我们同时注意到在执行 String s1 = "kevin" 后不会有新的对象产生。他首先会到pool中去寻找是否有一个内容为kevin的对象存在,这里找到这样一个对象。他就把引用s1执行pool中的这个对象。所以不会有新的对象产生。同理我们知道s3 和s1指向pool中的同一对象。而执行 String s2 = new String ("kevin") 时,他首先查看pool,发现有一个这样一个内容为kevin的对象存在,那么就不必在pool中创建这样一个对象了。接着他执行构造方法在堆中创建一个内容为kevin的对象,由s2指向。我们要注意的尽管堆中有两个内容为kevin的对象,他们仅仅是内容相同而已,他们的引用是不想同的。

      同样的问题如下:

               

package com.ys.String;

public class StringTest {
	
	public static void main(String[] args) {
		String s1 = "kevin";		
		String s2 = "ke";
		String s3 = "vin";
		
		System.out.println(s1 == "ke" + "vin");
		System.out.println(s1 == "ke" + s3);
	}
}

    输出会是如何呢?  

true
false

     产生这样的原因是:当 + 两边都是字面值(常量)的时候,其连接成一个字符串。在到pool中看是否存在一个内容为kevin的对象。本例中存在,所以返回true;而当 + 号两边有一边不是字面值的时候其会在堆中分配空间。即是说:s1在pool中而“ke” + s3 在堆中。所以返回false。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值