首页 理论教育 对Java语言中String类源代码的深度研究

对Java语言中String类源代码的深度研究

时间:2024-03-25 理论教育 版权反馈
【摘要】:java语言中String类源代码的深入研究吴道荣吴道勇摘要:在java程序设计中,有百分之五六十的代码是和字符串打交道,文章针对String类toString()方法、equals()方法源代码进行分析,从典型案例中详述String类的String Pool中对象和heap中对象,论述清楚String类中一些很难理解的“陷阱”和知识难点。通常,to String方法会返回一个“以文本方式表示”此对象的字符串。输出的结果都是:aaa它们调用的toString方法不是Object定义的to String方法,而是String类定义的to String方法。

对Java语言中String类源代码的深度研究

java语言中String类源代码的深入研究

吴道荣 吴道勇

摘 要:在java程序设计中,有百分之五六十的代码是和字符串打交道,文章针对String类toString()方法、equals()方法源代码进行分析,从典型案例中详述String类的String Pool中对象和heap中对象,论述清楚String类中一些很难理解的“陷阱”和知识难点。

关键词: Java Web编程对象toString方法equals方法

一、引言

在java程序设计中,有百分之五六十的代码是和字符串打交道,因此String类在java基础知识中显得尤其重要,而String中的一些知识点又有一些“陷阱”较难理解,本文将对其进行分析研究。

二、String类

String类代表字符串。Java程序中的所有字符串字面值(如“abc”)都作为此类的实例。

字符串是常量,它们的值在创建之后不能更改。字符串缓冲区支持可变的字符串。因为String对象是不可变的,所以可以共享。例如:

String str="abc";

等效于:

char data[]={‘a’,‘b’,‘c’};

String str= new String(data);

String是常量,其对象一旦创建完毕就无法改变。当使用“+”拼接字符串时,会生成新的String对象,而不是向原有的String对象追加内容。

Java程序中底层代码有一些“陷阱”,如果不清楚底层代码的编写,就很难搞清楚一些比较典型的程序的结论。

三、String类的toString()分析

(一)程 序

public class ObjectTest

{

 public static void main(String[]args)

  {

   Object object= new Object();

   System.out.println(object);

   System.out.println(object. toString());

   String str="aaa";

   System.out.println(str);

   System.out.println(str. toString());

   Student student= new Student();

   System.out.println(student);

   System.out.println(student. toString());

  }

}

class Student extends Object

{

   public StringtoString()

  {

    return"Hello World";

  }

}

(二)分析

当将对象传递给print方法和println方法时,将自动调用一个to String,以获得被打印对象的字符串形式的描述。实际上会打印出引用所指对象的to String()方法的返回值,因为每个类都直接或间接地继承自Object,而Object类中定义了to String(),因此每个类都有to String()这个方法。

通常,to String方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。

1.Object类中的public String to String()方法

Object类中的public String to String()返回该对象的字符串表示。

Object类的to String方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:

get Class(  ).get Name(  )+‘@’+ Integer. to Hex String(hash-Code(  ))

程序中:

System.out.println(object);和System.out.println(object.to String(  ));是等价的。

输出的结果都是:

java.lang.Object@ de6ced

它们调用的是Object定义的to String方法。

2.String类中的public String to String()方法

String类中的public String to String()返回此对象本身(它已经是一个字符串)。

程序中:

System.out.println(str);和System.out.println(str. to String());是等价的。

输出的结果都是:

aaa

它们调用的toString方法不是Object定义的to String方法,而是String类定义的to String方法。

3.自己定义类中的public String to String()方法

程序中:

System.out.println(student);和System.out.println(student.to String());是等价的。

输出的结果都是:

Hello World

它调用的to String方法是在本程序Student类自己定义的to String方法。Student类自己定义的to String方法返回“Hello World”字符串。

四、String类的equals(  )方法和“==”分析

(一)程 序

public class String Test

{

  public static void main(String[]args)

   {

    String str1= new String("aa");

    String str2= new String("aa");

    System.out.println(str1.equals(str2));

    String str3="aa";

    String str4="aa";

    System.out.println(str3.equals(str4));

    Object object1= new Object();

    Object object2= new Object();

    System.out.println(object1.equals(object2));

    System.out.println(object1.equals(object1));

}

}

(二)分 析

1.String类的equals()方法和“==”

对于String类的equals()方法来说,它主要是用来判断当前字符串与传进字符的内容是否一致。对于String对象的相等性判断来说,请使用equals()方法,而不要使用“==”。

String类equals方法的源代码:

publicboolean equals(Object an Object)

{

  if(this== an Object)

   { (www.xing528.com)

    return true;

   }

   if(an Object instance of String)

   {

   Stringanother String=(String) an Object;

   int n= count;

   if(n== another String. count)

    {

     char v1[]= value;

     char v2[]= another String.value;

     int i= offset;

     int j= another String.offset;

     while(n--!= 0)

     {

      if(v1[i++]!= v2[j++])

         return false;

     }

     return true;

    }

   }

   return false;

}

程序中,System.out.println(str1.equals(str2));输出的结果是: true; System.out.println(str3.equals(str4));输出的结果是: true。

2.Object类的equals()方法和“==”

Object类当中定义了equals()方法,因此java中的每个类都具有该方法,对于Object类的equals()方法来说,它是用来判断调用equals()方法的引用与传进来引用是否一致,即这两个引用指向的对象。对于Object类的equals()方法来说,它等价于“==”。

Object类equals方法的源代码:

publicboolean equals(Object obj)

{

return(this== obj);

}

程序中,System.out.println(object1.equals(object2));输出的结果是: false; System.out.println( object1.equals(object2));输出的结果是: true。

五、String类的String Pool中对象和heap中对象的分析

(一)程 序

public class ObjectTest2

{

  public static void main(String[]args)

   {

     Object object1= new Object();

     Object object2= new Object();

     System.out.println(object1== object2);

     String str1= new String("wang");

     String str2= new String("wang");

     System.out.println(str1== str2);

     String str3="zhang";

     String str4="zhang";

     System.out.println(str3== str4);

     String str5= new String("zhao");

     String str6="zhao";

     System.out.println(str5== str6);

     String str7="hello";

     String str8="hel";

     String str9="lo";

     System.out.println(str7== str8+ str9);

     System.out.println(str7=="hel"+"lo");

   }

}

(二)分 析

1.相等性的比较(= =)

(1)对于原生数据类型来说,比较的是左右两边值是否相等。

(2)对于引用类型来说,比较左右两边是否指向同一个对象或者两边的引用地址是否相同。

程序中,System.out.println(object1== object2);是对于引用类型的比较。Object1、object2分别指向heap中两个不同对象的地址。输出的结果是: false。

程序中,System.out.println(str1== str2);也是对于引用类型的比较。Str1、str2分别指向heap中两个不同对象的地址。输出的结果是: false。

2.String Pool(字符串池)

(1) String s=“aaa”;(采用字面值方式赋值)。

①查找String Pool中是否存在“aaa”这个对象,如果不存在这个对象,则在String Pool中创建一个“aaa”对象,然后将String Pool中的这个“aaa”对象的地址返回来,赋给引用变量s,这样s会指向String Pool中的这个“aaa”字符串对象。

②如果存在,则不创建任何对象直接将String Pool中的这个“aaa”对象地址返回来,赋给s引用。

程序中,System.out.println(str3== str4);的str3、str4指向String Pool中同一个对象“zhang”的地址。输出的结果是: true。

(2) String s= new String(“aaa”)。

①首先在String Pool中查找有没“aaa”这个字符串对象,如果有则不在String Pool中再去创建“aaa”这个对象了,直接在堆(heap)中创建一个“aaa”字符串对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中创建的这个“aaa”字符串对象。

②如果String Pool中没有“aaa”这个字符串对象,则首先在String Pool中创建一个“aaa”对象,然后再在堆(heap)中创建一个“aaa”对象,然后将堆中的这个“aaa”对象的地址返回来,赋给s引用,导致s指向了堆中所创建的这个“aaa”对象。

程序中,System.out.println(str5== str6);的str5指向heap中的“zhao”地址,str6指向String Pool中“zhao”的地址。输出的结果是: false。

(3) String类的intern方法。

String类的intern方法返回字符串对象的规范化表示形式。

一个初始为空的字符串池,它由类String独自维护。

当调用intern方法时,如果String Pool中已经包含一个等于此String对象的字符串[用equals(Object)方法确定],则返回池中的字符串。否则,将此String对象添加到String Pool中,并返回此String对象的引用。

它遵循以下规则:对于任意两个字符串s和t,当且仅当s.equals(t)为true时,s. intern()== t. intern()才为true。

所有字面值字符串和字符串赋值常量表达式都使用intern方法进行操作。

程序中,System.out.println(str7== str8+ str9);的str7指向String Pool中的“hello”对象,str8指向heap中的“hel”对象,str9指向heap中的“lo”对象,而str8+ str9在heap中生成了另一个对象,等价于new String(“hello”)。输出的结果是: false。

程序中,System.out.println(str7== str8+ str9);的str7指向String Pool中的“hello”对象,“hel”是String Pool中的对象,“lo”也是String Pool对象,而str8+ str9就返回String Pool中的“hello”对象。输出的结果是: true。

六、结束语

文章深入String类toString()方法、equals()方法对源代码进行分析,从典型案例中详述String类的String Pool中对象和heap中对象,论述清楚String类中一些很难理解的“陷阱”和知识难点,解决在使用String类时的一些实际问题。

参考文献:

[1]John Lewis William Loftus. Java程序设计教程[M].北京:电子工业出版社,2009.

[2]李芝兴,杨瑞龙. Java程序设计之网络编程:第2版[M].北京:清华大学出版社,2009.

[3]林信良. JDK 6 Java学习笔记[M].北京:清华大学出版社,2007.

[4]阎宏. Java与模式[M].北京:电子工业出版社,2002.

[5]李斌,王睿,何成芊.深入探讨Java中的String类[J].长沙通信职业技术学院学报,2009(9).

[6]张建东. Java程序设计教学探讨[J].科技信息,2009(8).

免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。

我要反馈