string类为什么不可变,string类型不可变是什么意思

  string类为什么不可变,string类型不可变是什么意思

  如何解决写爬虫IP受阻的问题?立即使用。

  为何Java中String类是不可变的(详解)

  公共最终类字符串

  实现java.io.Serializable,ComparableString,CharSequence {

  /**该值用于字符存储。*/

  私有最终字符值[];}String类的值保存在value数组中,由private final修饰。

  1.私有装饰表示外部类不能访问值,子类也不能访问。当然,String类不能有子类,因为类是用final修饰的。

  2.最后的修饰表示value的引用不会改变,但是value只会在String的构造函数中初始化,没有其他方法可以修改value数组中的value,保证了value的引用和值不会改变。

  所以我们说String类是不可变的。

  很多方法,比如subString,并不是对原来的String类进行操作,而是生成一个新的String类。

  公共字符串substring(int beginIndex) {

  if (beginIndex 0) {

  抛出新的StringIndexOutOfBoundsException(beginIndex);

  }

  int sub len=value . length-begin index;

  if (subLen 0) {

  抛出新的StringIndexOutOfBoundsException(subLen);

  }

  return (beginIndex==0)?this : new String(value,beginIndex,sub len);}为什么String被设置为不可变的?

  字符串常量池

  Java有8种基本数据类型

  整数类型:字节,短整型,长整型.包装类型是字节,短,整数,长浮点类型:浮点,双精度。包类型为浮点型,双字符类型:char。包类型是字符布尔类型:布尔型。包类型为布尔型。

  八种封装类型中,除了Float,Double没有实现常量池,其余的都实现了,当然都是通过元共享模式实现的。

  字符串类的常量池是在JVM级别实现的。

  为什么要有常量池?

  恒池是为了避免频繁的创建和销毁对象会影响系统性能,它实现了对象的共享。

  例如,字符串常量池,所有字符串在编译阶段都被放入一个常量池中。

  节省内存空间:常量池中所有相同的字符串常量被合并,只占用一个空间。

  节省运行时间:==比较字符串时比equals()快。对于两个引用变量,只用==来判断引用是否相等,使实际值相等。

  字符串常量池放在哪?

  jdk1.7之前没有讨论,从jdk1.7开始,字符串常量池就放在堆里了,然后本文的一切都是基于jdk1.8。

  下面的代码经常被问到。

  String str1= abc

  String str2= abc

  String str3=新字符串( ABC );

  String str4=新字符串( ABC );

  //true system . out . println(str 1==str 2);

  //false system . out . println(str 1==str 3);

  //false system . out . println(str 3==str 4);内存中的结构如下其中常量池中存的是引用

  解释上面代码的输出。在Java中有两种创建字符串对象的方法。

  String str1= abc

  String str2= abc

  //true system . out . println(str 1==str 2);当通过文字值创建一个字符串时,JVM将首先进入字符串池,找出对象“abc”是否存在。

  如果不存在,在字符串池中创建对象 abc ,然后将池中对象 abc 的地址赋给str1,这样str1将指向池中的字符串对象 abc 。

  如果存在,将不创建任何对象,直接返回池中对象‘ABC’的地址并赋给str2。结果为真,因为str1和str2指向同一个字符串池中的“abc”对象。

  String str3=新字符串( ABC );

  String str4=新字符串( ABC );

  //false system . out . println(str 3==str 4);当使用new关键字创建新的字符串对象时,JVM首先在字符串池中搜索字符串对象“abc”的存在,

  如果没有,首先在字符串池中创建一个 abc 字符串对象,然后在堆中创建一个 abc 字符串对象,然后将这个 abc 字符串对象在堆中的地址赋给str3。

  如果是这样,不要在池中创建“abc”对象,而是直接在堆中创建“abc”字符串对象,然后将堆中此“abc”对象的地址分配给str4。这样,str4就指向了堆中创建的这个‘ABC’string对象;

  因为str3和str4指向不同的string对象,所以结果为false。

  缓存HashCode

  创建String类时,hashcode缓存在hash成员变量中。因为String类是不可变的,所以hashcode不会改变。这样每次想用hashcode的时候,直接取就可以了,不用重新计算,提高了效率。

  公共最终类字符串

  实现java.io.Serializable,ComparableString,CharSequence {

  /**缓存字符串的哈希代码*/

  私有int哈希;//默认为0

  }可以用作HashMap的key

  由于String类的不可变属性,它经常被用作HashMap的键。如果String类是可变的,内容改变了,hashCode也会改变。当你根据这个键从HashMap中获取值时,你可能得不到值或者得到错误的值。

  线程安全

  不可变对象本质上是线程安全的,这可以避免在多线程环境中同步字符串。

  感谢您的阅读,希望您能从中获益良多。

  本文转自:https://blog.csdn.net/zzti_erlie/article/details/106872673

  推荐教程:《java教程》以上是Java中String类为什么不可变的详细内容(详解)。更多请关注我们的其他相关文章!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: