栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

String类

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

String类

String类不可变:

string类不能改变的是对象内的成员变量值.

String不可变的好处以及为什么不可变:

1.便于实现字符串常量池,节省空间.

在Java语言中,会大量使用到字符串,若每一册声明一个String创建一个新的String对象,这是多大的空间资源的浪费,Java中就提出了一个String Pool(字符串常量池)的概念,会在堆中开辟一块存储空间,当每次初始或一个String变量时,若该字符已经存在,就不会在创建新的字符串变量,而是返回已存在字符串的引用.

2.使多线程安全.

public class test {
  // 不可变的String
  public static String appendStr(String s) {
      s += "bbb";
      return s;//新的
  }

  // 可变的StringBuilder
  public static StringBuilder appendSb(StringBuilder sb) {
      return sb.append("bbb"); //还是原来的
  }

当程序将StringBuffer当做参数传值时,因为Java对象参数传递的是引用,所以将传入的StringBuffer类型的参数进行操作改变时,就会将原来的String对象操作而改变,有时候并不希望改变传入参数的值而是使用,所以String不可变安全性就体现在这里.

在并发场景下,多个线程访问同一个资源,是安全的,不会引发竞争,但对资源进行操作时是不安全的,不可变对象不能被写,所以保证了多线程的安全.

3.避免安全问题

网络连接地址URL,文件路径path,数据库连接中字符常常作为参数,反射机制所需要的String参数,其不可变性可以保证连接的安全性,如果字符串可以随意改变,就有可能被改变字符串指向对象的值,会引起严重的不可挽回的损失.

4.加快字符串的处理速度

由于String是不可变的,保证了hashcode的唯一性,于是在创建对象时其hashcode就可以放心的缓存了,不需要重新计算,通常Map将String作为键的原因,处理速度高于其他对象.hashMap中的键往往也是使用String.总体来说,String不可变的原因包括设计考虑,效率优化,以及安全性三大方面.

String的值真的没有办法改变吗:  

还是有办法将String的值进行改变的:

//通过反射改变String底层数组值
public static void main(String[] args) throws Exception {
        String s = "Hello World";
        System.out.println("s = " + s); //Hello World
        //获取String类中的value字段
        Field valueFieldOfString = String.class.getDeclaredField("value");
        //改变value属性的访问权限
        valueFieldOfString.setAccessible(true);
        //获取s对象上的value属性的值
        char[] value = (char[]) valueFieldOfString.get(s);
        //改变value所引用的数组中的第5个字符
        value[5] = '_';
        System.out.println("s = " + s);  //Hello_World
        System.out.println(s);//Hello_World
    }
String对象创建的方式:

String s1="aaa";

String s2=new String("aaa");

方式一中,会先在常量池中查找"aaa"这个字符对象是否存在,若存在就将常量池中的指向这个字符对象,若不存在,才会常见一个新的字符串对象.

方式二中,不论常量池中是否已经存在"aaa"这个对象,都会创建一个新的对象.

下列例子中创建了几个对象:

1.
String s = new String("abc")创建了几个对象
情况1: 创建两个对象
  String s = new String("abc");
  直接new对象,此前在字符串常量池中不存在"abc",此种情况在堆中创建一个对象,然后在字符串常量池中创建一个对象
情况2: 创建一个对象
  String s = "abc";
  String s1 = new String("abc");
  因为字符串常量池中已存在"abc",只需要在堆中创建即可.
2.    
创建了一个对象,底层优化创建了一个StringBuilder对象,append()追多个字符串对象,只产生一个对象.
 String st1 = "a" + "b" + "c";//只创建了一个字符串对象
 String st2 = "abc";
 System.out.println(st1 == st2);//true
3.
 String st1 = "ab";
 String st2 = "abc";
 String st3 = st1 + "c";//一旦发生拼接中有变量,会重新创建一个字符串对象
 System.out.println(st2 == st3);//false
String类中常用方法:

String();初始化一个新创建的String对象,使其表示一个空字符序列.

String("");初始化一个新创建的String对象,使其表示一个与参数相同的字符序列.

String(byte[] b ,0,length,chatset);通过使用指定chatset解码指定的byte子数组,构造一个新的String.

String(char[] b ,0,length);分配一个新的String,它包含取自字符组参数一个子数组的字符 .

String,StringBuffer,StringBuilder区别:

String值不可变,

StringBuffer 值可变,线程安全的,

StringBuilder 值可变,线程不安全的

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/785763.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号