java核心技术学习笔记4---String字符串

Java字符串就是Unicode字符序列。Java没有内置的字符串类型,而是在标准的java类库中提供了一个预定义类String。每个用双引号括起来的字符串都是一个String的实例。

代码单元

Java字符串由插入值序列组成。char数据类型是一个采用UTF-16编码表示Unicode代码点的代码单元。大多数的常用Unicode字符使用一个代码单元就可以表示,而辅助字符需要一对代码单元表示。

String str="Hello";

int n=str.length();//表示代码单元数量,值为5

char first=str.charAt(0);//返回位置0的代码单元,‘H’

若某个字符串是辅助字符序列,则使用charAt()获取的就是某个字符的部分代码单元,为避免这类情况发生,不要使用char类型。

codePointAt():能辨别一个代码单元是辅助字符的第一部分还是第二部分,并能返回正确结果。

int c=str.codePointAt(i);

if(Character.isSupplementaryCodePoint(c))  i+=2;

else   i++;

 

字符串常量池

String类对象被称为不可变字符串,不能直接修改Java字符串中的字符。每次对字符串的修改,其实返回的都是一个新的字符串。不可变字符串有一个优点:编译器可以将字符串共享。

字符串常量被存放到一个公共的存储池中,为下一次使提供了方便。每个类都有自己的常量池,例如整数的常量池、浮点数的常量池、字符串常量池。常量池是由编译器编译.java文件时,把字符串写入到.class文件中的。也就是说字符串常量池在字节码文件中,在JVM加载class文件到内存中后,JVM就可以使用class文件中的字符串常量池中的常量了。

在java源文件中,所有使用双引号括起来的字符串都是字符串常量,编译器都会把它们存储到class文件中。注意,编译器只存储字符串常量,而不存储字符串引用

编译器存储的过程如下:

1) 计算字符串常量表达式得出结果

2) 查看字符串常量池中是否已经存在了该字符串常量

        如果存在,什么都不做

        如果不存在,存储该字符串常量到字符串常量池中

常量池中存放的是字符串常量,而字符串变量则指向存储池中相应的位置。

 

不同方式构造字符串的区别

1) 不使用构造器的方式,例如:String s = “a”;

加载class文件到内存中,在内存中找到class文件的字符串常量池,并把“a”的地址赋给引用s。

2) 使用构造器的方式,例如:String s = new String(“a”);

在内存中创建字符串空白对象,找到class文件的字符串常量池,并把“a”复制到空白对象中,然后返回这个对象的地址给引用s。

 

String s1 = “abc”;

String s2 = “abc”;

System.out.println(s1 == s2);//true

在编译时,“abc”被存储到字符串常量池中去了,再程序运行时JVM首先把字符串常量池中“abc”的地址赋给了引用s1,然后再次把“abc”的地址赋给了s2。所以,s1==s2返回的是true。

 

String s1 = new String(“abc”);

String s2 = “abc”;

System.out.println(s1 == s2);//false

在编译时,“abc”被存储到字符串常量池中去了,再程序运行时JVM在内存中创建了一个空白对象,然后copy字符串常量池中“abc”的内容到空白对象,最后返回该对象的地址给引用s1。接下来再把字符串常量池中“abc”的地址赋给引用s2。所以,s1==s2返回的是false。

 

String s1 = “abc”;

String s2 = “a”;

String s3 = s2 + “bc”;

System.out.println(s1 == s3);//false

  在编译时,“abc”、“bc”被存储到字符串常量池中去了,再程序运行时JVM首先把字符串常量池中“abc”的地址赋给了引用s1。而s3=s2+“bc”这句代码因为编译器优化使用了StringBuilder类的toString()方法,而该类的toString()方法内部使用String类的构造器,也就是说s3是通过String类的构造器创建的,所以s1==s3的结果是false。

 

检测字符串是否相等

不要用==运算符检测两个字符串是否相等,因为这个运算符只能够判断两个字符串是否在同一个位置。因为只有字符串常量是共享的,而+或subString等操作产生的结果都不是共享的,所以用==运算符判断两个字符串相等会出现很多糟糕的bug,应该使用s.equals(t)方法,该方法中s和t可以是字符串常量也可以是字符串变量。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值