woaidongmao

文章均收录自他人博客,但不喜标题前加-[转贴],因其丑陋,见谅!~
随笔 - 1469, 文章 - 0, 评论 - 661, 引用 - 0
数据加载中……

Java中的String使用及注意事项

Java中使用字符串有一个非常重要的规则必须记得,一个字符串对象一旦被配置,它的内容就是固定不可变的。例如下面这个声明:

String str = "caterpillar";

这个声明会配置一个长度为11、内容为caterpillar的字符串对象,您无法改变这个字符串对象的内容。不要以为下面的语句就是改变一个字符串对象的内容:

String str = "Just";

str = "Justin";

事实上在这个程序片段中会有两个字符串对象,一个是Just字符串对象,长度为4;一个是Justin字符串对象,长度为6,两个是不同的字符串对象。您并不是在Just字符串后加上in字符串,而是让str名称引用自Justin字符串对象。图6-2展示出了这个概念。

clip_image001

6-2  使用=作字符串指定的意义

Java中,使用“=”将一个字符串对象指定给一个变量名称,其意义为改变该名称所引用的对象,原来被引用的字符串对象若没有其他名称来引用它,就会在适当的时候被Java的“垃圾回收”(Garbage Collection)机制回收。在Java中,程序设计人员通常不用关心无用对象的资源释放问题,Java会检查对象是否不再被引用,没有被任何名称引用的对象将会被回收。

Java执行时会维护一个String(Pool)。对于一些可以共享的字符串对象,会先在String池中查找是否存在相同的String内容(字符相同),如果有就直接返回,而不是直接创造一个新的String对象,以减少内存的耗用。如果在程序中使用下面的方式来声明,则实际上是指向同一个字符串对象:

String str1 = "flyweight";

String str2 = "flyweight";

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

当直接在程序中使用""来包括一个字符串时,该字符串就会在String池中,上面的程序片段中的flyweight就是这样的情况。flyweight在程序中会有一个实例,而str1str2同时引用自flyweight。图6-3表示了这个概念。

clip_image002

6-3  字符串变量str1str2同时引用自flyweight

Java中如果==被使用于两个对象类型的变量,它是用于比较两个变量是否引用自同一对象,所以在图6-3中当str1==str2比较时,程序的执行结果会显示true

再来看看关于Stringintern()方法,先看一下API说明的节选(翻译)

intern()方法被调用时,如果池(Pool)中已经包括了相同的String对象(相同与否由equals()方法决定),那么会从池中返回该字符串,否则原String对象会被加入池中,并返回这个String对象的引用。

这段话其实说明了Flyweight模式(参见本章的网络索引) 的运作方式,直接使用范例6.4来说明会更清楚。

Ü 范例6.4  InternString.java                                                     

public class InternString {

    public static void main(String[] args) {

        String str1 = "fly";

        String str2 = "weight";

        String str3 = "flyweight";

        String str4 = null;

 

        str4 = str1 + str2;

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

 

        str4 = (str1 + str2).intern();

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

    }

}

 

style='font-family:宋体'>使用图形来说明这个范例,在声明str1str2str3后,String池中的状况如图6-4所示。

 

clip_image003clip_image004

6-4  字符串池示意

Java中,使用+串联字符串会产生一个新的字符串对象,所以在程序中第一次比较str3str4对象是否为同一对象时,结果会是false,如图6-5所示。

clip_image005

6-5  字符串加法会产生新的字符串

intern()方法会先检查String池中是否存在字符部分相同的字符串对象,如果有就返回。由于程序中之前已经声明flyweight字符串对象,intern()String池中发现了它,所以直接返回。这时再进行比较,str3str4所指向的其实会是同一对象,所以结果会是true,如图6-6所示。

clip_image006

6-6  intern()会返回String池中字符串对象的引用

由以上的说明也得出一个结论,==Java中被用来比较两个变量名称是否引用自同一对象,所以不可以用==来比较两个字符串的字符内容是否相同。例如:

String str1 = new String("caterpillar");

String str2 = new String("caterpillar");

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

虽然两个字符串对象的字符值完全相同,但实际上在这个程序片段中,产生了两个String的实例,str1str2分别引用自不同的实例。所以使用==比较时结果会显示false。如果要比较两个字符串对象的字符值是否相同,要使用equals()方法,以下的写法才会显示true的结果:

String str1 = new String("caterpillar");

String str2 = new String("caterpillar");

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

 

posted on 2009-08-19 12:00 肥仔 阅读(553) 评论(0)  编辑 收藏 引用 所属分类: Web-后台


只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理