day_7/28(浅谈String类)

一、String类是什么?

        String类代表字符串,Java 程序中的所有字符串文字(例如“abc”)都被实现为此类的实例

也就是说,Java 程序中所有的双引号字符串,都是 String 类的对象,字符串不可变,它们的值在创建后不能被更改。

二、String常用的构造函数

        1、public String(){}

                创建一个空白字符串对象,不包含任何内容;

例: String str = new String();

        System.out.println(str);

        结果:

      这里为什么什么都没有呢?什么都看不到啊,其实str是这样的  ""  ,所以什么都看不见。

        2、public String(char [] chs){}

                根据字符数组的内容,来创建字符串对象;

例:    char [] ch = {'a','b','c'};

        String str = new String(ch);

        System.out.println(str);

        结果: abc

       结果很简单,很显然,但是它是如何实现的呢?怎么把字符数组里面的单个字符连接成一个字符串的呢?我会这么做:

        String str = new String();

        char [] ch = {'a','b','c'};

        for(int i = 0;i<ch.length;i++){

                str += ch[i];

        }

        System.out.println(str);

        结果: abc

        这样做可以实现,先是创建一个空的String类型的对象str,之后用字符串连接符‘+’,把char数组里面的每个字符连接到str后面,就实现了把一个字符数组转换成了字符串;接下来再看看String类的源码,看看源码里面这个 public String(char [] chs){} 是如何实现的;       

 写上如上两句代码,调用String类的带一个字符数组参数的构造方法,按住Ctrl,点击new后面的String构造方法,进入如下页面:

 进来之后发现,这里也看不到做了什么啊,看看注释,“分配一个新的{@code String},使其表示字符数组参数中当前包含的字符。这个复制字符数组的内容;后续修改字符数组不影响新创建的字符串。  @param value字符串的初始值”,继续往下看,按住Ctrl点击this:

 这里就可以看到了,前面把字符数组的地址和长度传进来,之后这里就开始返回byte类型的数组或 "" 值了,字符数组长度是0的话,那么就创建一个内容为空的对象,接下来这个COMPACT_STRINGS是一个静态的常量

 下一句,创建一个byte类型的名叫val的数组,调用StringUTF16类下面的compress方法,之后这个方法返回一个byte类型的数组,这时创建的String对象里面的值就是val的值,继续往下看:

 这里终于开始复制了,把一开始那个字符数组以及长度传入,开始复制,里面为什么要判断字符数组(ch)里面是否有(字符码)大于0xFF的字符呢?我们看前面,如果这里复制成功了,那么这个String对象的code就会被设置成LATIN1,这里看完,再回到前面:

前面两个if判断都没有创建对象的时候就到下面这两句代码了,你看,一上来就把code设置成UTF16,之后再创建对象,还没完,再来看看这个toBytes是个什么牛马方法,

这里的toBytes就开始复制了,先看调用的newBytesFor方法

 很简单,就是把原来的字符数组(ch)的长度左移一位,就是相当于乘以2,再看putChar方法:

 前面不是判断了字符数组(ch)里面单个字符的字符码有没有大于0xFF的,前面的逻辑判断决定了进到这个方法,那么肯定是有字符码大于0xFF的字符的,然后这里就来了啊,把高八位放在前面,低八位放在后面,为什么又是16位呢?因为Unicode编码是16位的啊,而byte只占一个字节,只有八位,所以要用两个byte数组元素来存,至于为什么是高八位在前,低八位在后呢?其实低八位在前高八位在后也是可以的,这个问题我猜测应该是看系统的存储方式了,系统不同可能会有差别,看看HI_BYTE_SHIFT和LO_BYTE_SHIFT的声明

 那个静态语句快里面就是决定了数据是高八位在前还是低八位在前,决定这个东西的就是isBigEndian();方法,这个方法是用native声明的,我不懂,找度娘:

 看,这个方法应该就是我猜测的那样,用来判断系统底层存储数据的方式的。

这些了解完之后,再回到前面,toBytes把字符串数组存到byte类型数组里面之后再返回这个数组,对象创建完成。

        对比一下我开始的实现,看起来很简单,一下就实现了,扒出源码,才知道自己只不过是站在巨人的肩膀上罢了,写出这些代码的人是真的牛哥,全服。

        3、public String(String original){}

                根据传入的字符串内容,来创建字符串对象;

        4、String str = "abc";

                直接赋值的方式创建字符串对象,内容就是abc;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值