共同学习Java源码--常用数据类型--String(一)
来源:互联网 发布:专业音频编辑软件 编辑:程序博客网 时间:2024/06/09 18:54
首先来看String类,这是Java开发者最常用的一个类,也是最常用的引用类型。
先来看String类的修饰符和实现的接口:
public final class String implements java.io.Serializable, Comparable<String>, CharSequence {
String类成员变量中有一个char数组,来表示String的"值",这种写法很明显表明这段代码的作者是个多年经验的C程序员,C语言里字符串用char数组表示,而且[]在变量名的后面。
private final char value[];
String类的成员变量中还有一个很有意思的东西:
<pre name="code" class="java">private static final ObjectStreamField[] serialPersistentFields = new ObjectStreamField[0];这个数组所在的类暂时先不考虑,这个成员变量上面的注释是这么写的:String类是序列化流协议中的一个特殊实现,一个String实例最初以TC_String格式写入到ObjectOutputStream中,String由DataOutput.writeUTF写成的,一个新的句柄生成后指向流中的String实例的所有未来引用。我查了一下,这个类是用来声明可序列化字段的类,我理解这个变量就是这个数组用来存句柄,也就是标识String实例的整数值,但是这个数组目前是final的且长度为0,估计是目前尚未开发但以后会起作用的成员变量。
不纠结这个了,接下来看构造方法,有很多构造方法下面逐一解释一下:
<pre name="code" class="java">public String() { this.value = new char[0];}这个无参的构造方法将value这个char数组初始化为一个长度为0的char数组,换句话说就是一个空字符串。
<pre name="code" class="java">public String(String original) { this.value = original.value; this.hash = original.hash;}
这个构造方法传入一个String变量作为唯一参数,构造方法内将这个参数的value也就是char数组传给本String类对象的value,也就是实现了值的传递,接下来又传递了参数的hash值,也就是将参数的索引也传给了本对象。
<pre name="code" class="java">public String(char value[]) { this.value = Arrays.copyOf(value, value.length);}这个构造方法传入一个char数组,然后将char数组通过数组工具类的拷贝方法全部拷贝到本类的value属性,也就是只复制了值。
<pre name="code" class="java">public String(char value[], int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > value.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } this.value = Arrays.copyOfRange(value, offset, offset+count);}
这个构造方法传入三个参数,一个是char数组,一个是要复制的数组的起点下标,另一个是要复制的数组的长度。如果下标和长度都小于0,那么会出现异常。这个构造方法实现的是将从传入的char数组中的指定下标开始复制该char数组的count个元素到本对象的value中
<pre name="code" class="java">public String(int[] codePoints, int offset, int count) { if (offset < 0) { throw new StringIndexOutOfBoundsException(offset); } if (count < 0) { throw new StringIndexOutOfBoundsException(count); } // Note: offset or count might be near -1>>>1. if (offset > codePoints.length - count) { throw new StringIndexOutOfBoundsException(offset + count); } final int end = offset + count; // Pass 1: Compute precise size of char[] int n = count; for (int i = offset; i < end; i++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) continue; else if (Character.isValidCodePoint(c)) n++; else throw new IllegalArgumentException(Integer.toString(c)); } // Pass 2: Allocate and fill in char[] final char[] v = new char[n]; for (int i = offset, j = 0; i < end; i++, j++) { int c = codePoints[i]; if (Character.isBmpCodePoint(c)) v[j] = (char)c; else Character.toSurrogates(c, v, j++); } this.value = v;}这个构造方法较长,实际上很简单就是通过传入一个int数组,这个数组里存的是ASC码,然后后两个参数和上面那个构造方法的后两个参数一样,都是取下标和长度,然后把int数组中的指定元素以ASC码的形式取出来转换成字符再拼接,举个例子:
<pre name="code" class="java">String s=new String(new int[]{56,57,58},0,2);最后s的值是89,因为取的是int数组里的第1位开始后的两位,也就是将ASC码中的56、57转换为字符拼接,也就是89。
</pre><pre name="code" class="java">下一篇继续写String类的源码分析
0 0
- 共同学习Java源码--常用数据类型--String(一)
- 共同学习Java源码--常用数据类型--String(二)
- 共同学习Java源码--常用数据类型--String(三)
- 共同学习Java源码--常用数据类型--String(四)
- 共同学习Java源码--常用数据类型--String(五)
- 共同学习Java源码--常用数据类型--String(六)
- 共同学习Java源码--常用数据类型--String(七)
- 共同学习Java源码--常用数据类型--String(八)
- 共同学习Java源码--常用数据类型--String(九)
- 共同学习Java源码--常用数据类型--String(十)
- 共同学习Java源码--常用数据类型--String(十一)
- 共同学习Java源码--常用数据类型--String(十二)
- 共同学习Java源码--常用数据类型--String(十三)
- 共同学习Java源码--常用数据类型--String(十四)
- 共同学习Java源码--常用数据类型--String(十五)
- 共同学习Java源码--常用数据类型--String(十六)
- java源码学习之String(一)
- java源码学习一:String源码
- HSV(HSL)颜色空间及其应用
- 算法系列(1)排序算法
- java之查看字符、字符串的ASCII码
- oracle登录时会报错 initialization error
- laravel框架学习(路由)
- 共同学习Java源码--常用数据类型--String(一)
- 《GPU编程与CG语言之阳春白雪下里巴人》 读书笔记1
- Redis入门很简单之六【Jedis常见操作】
- 解决Error inflating class android.support.v7.widget.RecyclerView
- MAC 显示与隐藏文件
- AS Gradle 使用笔记
- iOS程序支持64位以及project.pbxproj文件的介绍
- xcode删除最近打开的工程
- 关于RunLoop的一些的资料整理记录