一、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;