java的String探讨

1,背景

        Java的String不是java的基本类型,因而其与java的基本类型如int,float等有一些差别,同时java的String使用很广泛,因而有必要对其进行深入的学习。

2,本文结构

<1>   第3部分:基础理论

<2>   第4部分:字符串的比较:==与equals() 的区别

<3>   第5部分:String , StringBuffer , StringBulider性能的比较

3,基础理论

        我们先来看看javaAPI。Java的String类位于java.long目录下,其定义如下:

public final class String extends Object implements Serializable,Comparable<String>,CharSequence

从中,我们知道String类是一个final类,继承了Object类,实现了三个接口。根据这些信息,可以得知String类不能被继承,其拥有Object类的所有方法。首先,需要强调的是String是一个类,因此,要使用String就需要像其他类一样,先要实例化一个String的对象,通过该实例对象,可以对一个字符串进行很多操作;其次,java的基本数据类型不是类,可以直接使用基本数据类型。那么就有疑问了,既然String使用的这么频繁,为神马不把它定义为一个基本数据类型呢?每次使用一个String都要像使用类一样,多么不方便啊。其实这个问题很简单的吧,因为我们使用字符串是不定长的,而每个基本数据类型在内存中都是定长的,如char是2位,int是4位。为了进一步的说明问题,我们就再深入一点。

    Jvm的存储机制把存储类型分为:寄存器、栈、堆、静态存储区、常量存储区。寄存器在处理器中,我们不直接操作,有处理器分配;栈在内存中,其容量很小,但读写速度很快,仅次于寄存器,其地址的分配是由处理器的栈指针控制的,栈指针下移分配一个新的空间,上移则释放一个空间,因而,能够进入栈的必须是长度固定的java元素,如对象的引用,基本数据类型等;堆也在内存中,容量大点,当然存取速度就相对慢了,其中主要存放的是对象的实例(由new关键字产生的部分);静态存储区也在内存中,存放java静态元素,如java的static关键字修饰的部分;常量存储区就是硬盘了(通常是,当然也可以是rom类型的存储)。知道了这个,就容易理解为什么String不是基本数据类型了吧。

    String既然是一个类(一个final类),那么就好办了,我们把它看成一个类,也就不迷糊了。如:

String str = new String(“how many instances?”);

//有几个对象?答2个,一个字符串对象的实例(new String())和该实例的一个拷贝。

String str2 = “how many instances?”;

//有几个对象?答1个

4,字符串的比较:==与equals() 的区别

         刚接触String时,对两个字符串的比较有些头疼,不知道何时该用“==”,何时该用“equals(Object object)”方法。一句话,”==”比较的是引用,”equals(Object object)”比较的是内容.为了便于说明问题,看下面的例子:

String str1 = new String("1234");

String str2 = new String("1234");

System.out.println("the boolean is:"+(str1.equals(str2)));

System.out.println("the boolean is:"+(str1==str2));

//结果是什么呢?前面的是true,后面的当然是false了。“new String("1234")“创建的是字符串"1234"的一个副本,那么很显然,str1str2的内容是相同的,但在内存中的地址是不同的。

5,String ,StringBuffer , StringBulider性能的比较

        String在上面已经说了一些,由于其是final类,因而当我们定义一个字符串后,其值是不能改变的。那么就有了以下的疑问:

private String str ="abc";

str = "efg";

System.out.println(str1);

//输出当然是 efg。这不是改变str的值了吗。这里并不是改变了str的值,而是新建了一个String对象,覆盖了str。因为根据java API的说明,String str = "abc"等价于

String str = new String(“abc”).因而第二行相当于

str = new String("efg").

因而当我们大量使用上述方法来改变一个字符串的值的时候,就相当于创建了大量的String对象不断的覆盖原来的字符串对象。这样做当然就造成了程序执行效率的下降,那么StringBuffer就及时的出现了。

查看API,我们发现StringBuffer也是一个final类,然而其提供了一些方法使StringBuffer的值可以随心所欲的改变,而不必重新创建StringBuffer对象。如append()和insert()方法。因而在执行效率上就比String高了。

        那么为什么又出现了StringBulider了呢?StringBuffer很好,但其是线程安全的,而StringBulider是非线程安全的,在单线程情况下效率要比StringBuffer高。这两个就这么大差别。

        总结一下,1,当不是很频繁的改变一个字符串的值的时候,使用String相当简单方便;2,当涉及对一个字符串的值频繁的改变的时候,使用StringBuffer效率高;3,当单线程情况下对一个字符串的值频繁改变时,使用StringBulider效率高。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值