谈谈你对java中String的了解

        String是java中的不可变字符串类,这个不可变指的是String对象一旦被创建,它的内容将不可被改变,因为String对象是不可变对象,String类是不可变类,不可变类的特点是:所有的属性都用final修饰,这些属性都是在构造方法中被赋值的,又因为都用final修饰,所以这些属性只能在构造对象的时候被赋值一次,后续将永远无法被修改。

        String类有一个char类型的数组,这个数组就是组成String对象的所有的字符的顺序集合,当然这个char数组也用final修饰了,所以String对象是一个不可变字符串对象,不可变对象天生就是线程安全的,即便是有多个线程并发访问它,也无法做到修改它的内容。所以String是一个线程安全的字符串类,适合使用于单线程及多线程场景下。

        但是它的不可变特性也给它带来了一个缺点,那就是,每次对于String对象的修改操作都会导致一个新的String对象被创建出来,所以当我们的业务需求是需要频繁地对字符串做修改操作时,应该用可变字符串StringBuilder或者StringBuffer来代替String,线程不安全的StringBuilder和线程安全的StringBuffer都提供了如append等操作方便我们实现对于字符串内容的修改,这些方法的调用都不会导致新的对象被创建,避免了内存开销,当修改操作完成之后,可以调用StringBuilder或者StringBuffer对象的toString方法将其转换为String对象。

        String可以算是我们在开发过程中最常用的一个类了,我们还经常将String对象用做HashMap的key,那么它为什么适合作为HashMap的key呢?

        首先因为String类对于hashCode和equals方法做了重写,它对于这俩方法的重写满足了HashMap的规约,这个规约是:两个对象可以具有相同的hashCode,当两个对象hashCode相同时,他们equals不一定为true;当两个对象hashCode不同时,它俩equals一定为false;当两个对象equals为true时,它俩一定具有相同的hashCode;当两个对象equals为false时,它俩的hashCode不一定不等。String类对于hashCode方法的实现是:用组成String对象的char数组的每一个字符做复合运算得到的int值作为此对象的hashCode,对于equals方法的实现是:逐一比较组成String对象的char数组的各个字符是否相同。String类对于这俩方法的实现满足了HashMap的规约,同时,hashCode方法的实现也降低了哈希碰撞发生的概率,保证了HashMap的操作性能。并且,因为String对象的不可变特性,也保证了对象的hashCode的不变性,以及equals方法的结果的不变性,避免了HashMap存储混乱的情况发生。

        再说说字符串常量池,在jvm的实现中,专门开辟了一块儿内存区域用于存储字符串常量,这块儿区域叫做字符串常量池,在低版本的jdk(jdk1.6之前)中,字符串常量池位于方法区,从jdk1.7开始,常量池被移到了堆内存中。我们在实际的开发中,当需要使用一个String对象的时候,我们通常会这样写:String str = "abc";这种写法会比String str = new String("abc");这样的写法更好,因为能够减少String对象的创建,new String这种写法还要在堆内存中创建一个String对象,而第一种写法直接将str引用指向字符串常量池中的"abc"这个常量,这也是字符串常量池存在的意义:那就是,减少字符串对象的创建,减少内存开销

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值