从今天开始简单开始读一遍jdk的源码,估计这个时间会很长,慢慢啃吧。。。。(首先说一句抱歉,因为很多图都是直接百度扣的,图太多了不能为每一个图附上原版链接,不好意思!)

  在网上看了很多的教程,读源码有一定的顺序,按照包的顺序:java.lang包,java.util包,java.util.concurrent包,java.util.concurrent.atomic包,java.lang.reflect包,java.lang.annotation包,java.util.concurrent.locks包,java.io包,java.nio包,java.sql包,java.net包;

  大概数了一下,有11个包,暂时就把这11个包读完应该就差不多了,应该可以对jdk源码会理解很多,而且中间可能会涉及到一些其他的知识,我也是新手,也顺便学一下;

  当然也不可能把所有的方法都慢慢的去分析、去读,重点看一些比较重要的方法看看,很多的重载方法和不常用的方法可以选择性的省略。。。适合自己的才是最好的!比如一个方法基本上都用不到的,我们就简单瞄两眼就可以了,用的频繁的方法可以去看看实现原理。

1.概述

  对于java.lang包我们可以说是用得很多了,但是一直没有系统的整理一下,比如一个很熟悉的类Object,如果让你说说这个类中有哪些方法啊?(亲身遇到的一个面试题。。。)

  先看看这个包下常用都有些什么类吧,借来的一个图,1优先级最高,4优先级最低

  1. 1) Object 1
  2. 2) String 1
  3. 3) AbstractStringBuilder 1
  4. 4) StringBuffer 1
  5. 5) StringBuilder 1
  6. 6) Boolean 2
  7. 7) Byte 2
  8. 8) Double 2
  9. 9) Float 2
  10. 10) Integer 2
  11. 11) Long 2
  12. 12) Short 2
  13. 13) Thread 2
  14. 14) ThreadLocal 2
  15. 15) Enum 3
  16. 16) Throwable 3
  17. 17) Error 3
  18. 18) Exception 3
  19. 19) Class 4
  20. 20) ClassLoader 4
  21. 21) Compiler 4
  22. 22) System 4
  23. 23) Package 4
  24. 24) Void 4

  下面这个更全面,描述了java.lang包下的类主要是负责哪些方面的;

2.Object类

  对于这个类很熟悉吧,所有的类默认都是继承这个类;

  1. //任何类默认都会继承这个类
  2. public class Object {
  3. //这个方法顾名思义,就是将一些native方法注册一下,可以简单理解成每一个native方法都连接着一个C/C++的具体实现
  4. private static native void registerNatives();
  5.  
  6. //此处的代码块静态会调用上面的这个native方法
  7. //所谓的native方法,就是底层用C/C++实现的,java可以有办法去调用这些其他语言的方法,可以了解一下JNI
  8. static {
  9. registerNatives();
  10. }
  11.  
  12. //这也是一个native方法,就是获取一个类的字节码文件
  13. public final native Class<?> getClass();
  14.  
  15. //获取一个类的hash值,简单说说哈希值,这个在map中用的比较多;其实任意对象----->通过一个hash函数计算------>得到一个很大的数字(这就是hashCode)---
  16. //---->这个hashCode进行取余计算等方式,就得到数组的下标;
  17. public native int hashCode();
  18.  
  19. //可以看到这里比较的就是两个对象的引用,换句话说就是看看两个对象是不是同一个对象
  20. public boolean equals(Object obj) {
  21. return (this == obj);
  22. }
  23.  
  24. //克隆,想想现实中的克隆人。。。这里就是克隆一个和原来对象一模一样的对象
  25. //注意,克隆分为浅克隆和深度克隆,深度克隆就是克隆出来的对象和原对象无关了,而浅克隆就是和原先对象有点关系,具体的什么关系呢?
  26. //我简单说说浅克隆,原先对象中保存了一个Person实例的引用,而克隆的对象中也保存的是同一个Person的引用,当在克隆对象中对这个引用进行修改,原对象也会牵连。。。
  27. protected native Object clone() throws CloneNotSupportedException;
  28.  
  29. //这个方法就是将当前类基本信息以字符串形式打印出来,一般就是类名+@+hashCode变为16进制
  30. public String toString() {
  31. return getClass().getName() + "@" + Integer.toHexString(hashCode());
  32. }
  33.  
  34. //多线程中用于随机唤醒一个线程的方法,这两个notify方法都要和wait方法一起用
  35. public final native void notify();
  36.  
  37. //唤醒所有线程
  38. public final native void notifyAll();
  39.  
  40. //让一个线程休息一下一定时间,这个方法会释放当前的锁,想了解的可以看看我以前的博客,或者自己看看资料
  41. //注意wait方法和sleep方法的区别
  42. public final native void wait(long timeout) throws InterruptedException;
  43.  
  44. public final void wait(long timeout, int nanos) throws InterruptedException {
  45. if (timeout < 0) {
  46. throw new IllegalArgumentException("timeout value is negative");
  47. }
  48.  
  49. if (nanos < 0 || nanos > 999999) {
  50. throw new IllegalArgumentException(
  51. "nanosecond timeout value out of range");
  52. }
  53.  
  54. if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
  55. timeout++;
  56. }
  57.  
  58. wait(timeout);
  59. }
  60.  
  61. //这个0可不是等待0秒啊,是等待无限长的时间,直到被唤醒
  62. public final void wait() throws InterruptedException {
  63. wait(0);
  64. }
  65.  
  66. //这个方法看看就好, 最没用的方法;主要用于jvm的垃圾回收,即使调用这个方法但是不保证一定立即进行回收。。。
  67. protected void finalize() throws Throwable { }
  68. }

3.String类

  关于这个类用得很多,初学的时候最多的就是比较String,StringBuffer,StringBulider。。。我就把常用的那些方法给说一下,很少用的方法选择性的删除

  1. package java.lang;
  2.  
  3. import sun.misc.FloatingDecimal;
  4. import java.util.Arrays;
  5.  
  6. abstract class AbstractStringBuilder implements Appendable, CharSequence {
  7. //看来这个StringBuilder本质上也是一个字节数组,和String不同的是这里没有被final修饰
  8. char[] value;
  9.  
  10. //字符数组的容量
  11. int count;
  12.  
  13. AbstractStringBuilder() {
  14. }
  15.  
  16. //根据传进来的参数确定字符数组的大小
  17. AbstractStringBuilder(int capacity) {
  18. value = new char[capacity];
  19. }
  20.  
  21. //返回字符数组中实际数据的数量
  22. public int length() {
  23. return count;
  24. }
  25.  
  26. //返回字符数组的最大容量
  27. public int capacity() {
  28. return value.length;
  29. }
  30.  
  31. //一下三个方法都是确保那个字符数组大小足够而进行的扩容操作;首先判断你要确保新字节数组多大,
  32. //如果新数组容量比原来数组大,那么就进行扩容,扩容的时候还需要进行判断,比较系统自动扩容之后
  33. //的容量和你所确保的容量做个对比,如果系统扩容还达不到你的要求,那么新字节数组的大小就用你确保的那个容量吧
  34. //最后就是将原来数组中的数据复制到新的数组中
  35. public void ensureCapacity(int minimumCapacity) {
  36. if (minimumCapacity > 0)
  37. ensureCapacityInternal(minimumCapacity);
  38. }
  39.  
  40. private void ensureCapacityInternal(int minimumCapacity) {
  41.  
  42. if (minimumCapacity - value.length > 0)
  43. expandCapacity(minimumCapacity);
  44. }
  45.  
  46. void expandCapacity(int minimumCapacity) {
  47. int newCapacity = value.length * 2 + 2;
  48. if (newCapacity - minimumCapacity < 0)
  49. newCapacity = minimumCapacity;
  50. if (newCapacity < 0) {
  51. if (minimumCapacity < 0)
  52. throw new OutOfMemoryError();
  53. newCapacity = Integer.MAX_VALUE;
  54. }
  55. value = Arrays.copyOf(value, newCapacity);
  56. }
  57.  
  58. //去除数组中多余的位置;比如一个数组最大容量为5,但是实际放了3个数据,空出来两个位置,于是
  59. //可以将对于的两个空位置去掉(其实就是将那是那三个数据复制到一个新的数组中,然后改变value引用)
  60. public void trimToSize() {
  61. if (count < value.length) {
  62. value = Arrays.copyOf(value, count);
  63. }
  64. }
  65.  
  66. //设置字节数组的长度,多余的空位置添加'\0',这其实就是代表空字符,可以理解为null
  67. public void setLength(int newLength) {
  68. if (newLength < 0)
  69. throw new StringIndexOutOfBoundsException(newLength);
  70. ensureCapacityInternal(newLength);
  71.  
  72. if (count < newLength) {
  73. for (; count < newLength; count++)
  74. value[count] = '\0';
  75. } else {
  76. count = newLength;
  77. }
  78. }
  79.  
  80. //根据传进来的索引获取字节数组对应的数据
  81. public char charAt(int index) {
  82. if ((index < 0) || (index >= count))
  83. throw new StringIndexOutOfBoundsException(index);
  84. return value[index];
  85. }
  86.  
  87. //截取字节数组的连续的某几个字符,放到一个新的字节数组中
  88. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
  89. {
  90. if (srcBegin < 0)
  91. throw new StringIndexOutOfBoundsException(srcBegin);
  92. if ((srcEnd < 0) || (srcEnd > count))
  93. throw new StringIndexOutOfBoundsException(srcEnd);
  94. if (srcBegin > srcEnd)
  95. throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
  96. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  97. }
  98.  
  99. //将字符数组某个位置的字符覆盖
  100. public void setCharAt(int index, char ch) {
  101. if ((index < 0) || (index >= count))
  102. throw new StringIndexOutOfBoundsException(index);
  103. value[index] = ch;
  104. }
  105.  
  106. //传入一个对象,将这个对象转化为字符串,然后将该字符串(就是一个字符数组)添加到当前字符数组的末尾
  107. //append方法就是在当前字符数组中后面添加所要添加的对象
  108. public AbstractStringBuilder append(Object obj) {
  109. return append(String.valueOf(obj));
  110. }
  111.  
  112. //首先要确保容量足够,再就是调用String类的getChars方法就是将传进去的str从0到最后,一次复制到value字节数组中
  113. public AbstractStringBuilder append(String str) {
  114. if (str == null) str = "null";
  115. int len = str.length();
  116. ensureCapacityInternal(count + len);
  117. str.getChars(0, len, value, count);
  118. count += len;
  119. return this;
  120. }
  121.  
  122. //将StringBuffer类型的字符字符数组复制到本类的字符数组中(首先要保证容量足够)
  123. public AbstractStringBuilder append(StringBuffer sb) {
  124. if (sb == null)
  125. return append("null");
  126. int len = sb.length();
  127. ensureCapacityInternal(count + len);
  128. sb.getChars(0, len, value, count);
  129. count += len;
  130. return this;
  131. }
  132.  
  133. //将一个字符数组的某一段复制到本类的字符数组当中
  134. public AbstractStringBuilder append(char str[], int offset, int len) {
  135. if (len > 0)
  136. ensureCapacityInternal(count + len);
  137. System.arraycopy(str, offset, value, count, len);
  138. count += len;
  139. return this;
  140. }
  141.  
  142. //在当前字符数组中添加boolean字符
  143. public AbstractStringBuilder append(boolean b) {
  144. if (b) {
  145. ensureCapacityInternal(count + 4);
  146. value[count++] = 't';
  147. value[count++] = 'r';
  148. value[count++] = 'u';
  149. value[count++] = 'e';
  150. } else {
  151. ensureCapacityInternal(count + 5);
  152. value[count++] = 'f';
  153. value[count++] = 'a';
  154. value[count++] = 'l';
  155. value[count++] = 's';
  156. value[count++] = 'e';
  157. }
  158. return this;
  159. }
  160.  
  161. //在当前字符数组最后中添加一个字符
  162. public AbstractStringBuilder append(char c) {
  163. ensureCapacityInternal(count + 1);
  164. value[count++] = c;
  165. return this;
  166. }
  167.  
  168. //在当前字符数组后面添加一个int类型(4个字节)的数据,要保证容量足够
  169. //后面还有添加各种数据类型long,double,float等省略
  170. public AbstractStringBuilder append(int i) {
  171. if (i == Integer.MIN_VALUE) {
  172. append("-2147483648");
  173. return this;
  174. }
  175. int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
  176. : Integer.stringSize(i);
  177. int spaceNeeded = count + appendedLength;
  178. ensureCapacityInternal(spaceNeeded);
  179. Integer.getChars(i, spaceNeeded, value);
  180. count = spaceNeeded;
  181. return this;
  182. }
  183.  
  184. //对一个字符数组中某一段进行删除,给出了起始位置和终点位置,可以看到就是利用的是数组的复制
  185. //重点System.arraycopy方法,可惜这是一个native方法,看不到源码
  186. public AbstractStringBuilder delete(int start, int end) {
  187. if (start < 0)
  188. throw new StringIndexOutOfBoundsException(start);
  189. if (end > count)
  190. end = count;
  191. if (start > end)
  192. throw new StringIndexOutOfBoundsException();
  193. int len = end - start;
  194. if (len > 0) {
  195. System.arraycopy(value, start+len, value, start, count-end);
  196. count -= len;
  197. }
  198. return this;
  199. }
  200.  
  201. //删除字符数组指定位置的字符
  202. public AbstractStringBuilder deleteCharAt(int index) {
  203. if ((index < 0) || (index >= count))
  204. throw new StringIndexOutOfBoundsException(index);
  205. System.arraycopy(value, index+1, value, index, count-index-1);
  206. count--;
  207. return this;
  208. }
  209.  
  210. //目的是为了让一个新的字符数组,代替本字符数组的某一段
  211. //其实还是通过数组的复制
  212. public AbstractStringBuilder replace(int start, int end, String str) {
  213. if (start < 0)
  214. throw new StringIndexOutOfBoundsException(start);
  215. if (start > count)
  216. throw new StringIndexOutOfBoundsException("start > length()");
  217. if (start > end)
  218. throw new StringIndexOutOfBoundsException("start > end");
  219.  
  220. if (end > count)
  221. end = count;
  222. int len = str.length();
  223. int newCount = count + len - (end - start);
  224. ensureCapacityInternal(newCount);
  225.  
  226. System.arraycopy(value, end, value, start + len, count - end);
  227. str.getChars(value, start);
  228. count = newCount;
  229. return this;
  230. }
  231.  
  232. //截取字符数组的某一段,其实就是新建了一个String类型的
  233. public String substring(int start, int end) {
  234. if (start < 0)
  235. throw new StringIndexOutOfBoundsException(start);
  236. if (end > count)
  237. throw new StringIndexOutOfBoundsException(end);
  238. if (start > end)
  239. throw new StringIndexOutOfBoundsException(end - start);
  240. return new String(value, start, end - start);
  241. }
  242.  
  243. //向StringBuilder中插入一个字节数组的某一段,省略好多的重载insert方法
  244. public AbstractStringBuilder insert(int index, char[] str, int offset,
  245. int len)
  246. {
  247. if ((index < 0) || (index > length()))
  248. throw new StringIndexOutOfBoundsException(index);
  249. if ((offset < 0) || (len < 0) || (offset > str.length - len))
  250. throw new StringIndexOutOfBoundsException(
  251. "offset " + offset + ", len " + len + ", str.length "
  252. + str.length);
  253. ensureCapacityInternal(count + len);
  254. System.arraycopy(value, index, value, index + len, count - index);
  255. System.arraycopy(str, offset, value, index, len);
  256. count += len;
  257. return this;
  258. }
  259.  
  260. //从前往后查看某个字符串的位置
  261. public int indexOf(String str) {
  262. return indexOf(str, 0);
  263. }
  264.  
  265. //从前往后其实就是调用String的indexof方法
  266. public int indexOf(String str, int fromIndex) {
  267. return String.indexOf(value, 0, count,
  268. str.toCharArray(), 0, str.length(), fromIndex);
  269. }
  270.  
  271. //从后往前找指定字符串的位置
  272. public int lastIndexOf(String str, int fromIndex) {
  273. return String.lastIndexOf(value, 0, count,
  274. str.toCharArray(), 0, str.length(), fromIndex);
  275. }
  276.  
  277. //逆序字符数组,实现很简单,不要看hasSurrogate了,反正我是没看懂这个boolean的。。。
  278. public AbstractStringBuilder reverse() {
  279. boolean hasSurrogate = false;
  280. int n = count - 1;
  281. for (int j = (n-1) >> 1; j >= 0; --j) {
  282. char temp = value[j];
  283. char temp2 = value[n - j];
  284. if (!hasSurrogate) {
  285. hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
  286. || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
  287. }
  288. value[j] = temp2;
  289. value[n - j] = temp;
  290. }
  291. if (hasSurrogate) {
  292.  
  293. for (int i = 0; i < count - 1; i++) {
  294. char c2 = value[i];
  295. if (Character.isLowSurrogate(c2)) {
  296. char c1 = value[i + 1];
  297. if (Character.isHighSurrogate(c1)) {
  298. value[i++] = c1;
  299. value[i] = c2;
  300. }
  301. }
  302. }
  303. }
  304. return this;
  305. }
  306.  
  307. //留给子类实现,直接打印字符串
  308. public abstract String toString();
  309.  
  310. //返回字符数组
  311. final char[] getValue() {
  312. return value;
  313. }
  314.  
  315. }

4.StringBuilder类

  有关于这个类其实很容易,就两层结构,final class StringBuilder extends AbstractStringBuilder,我们重点就在这个父类上,子类其实没做什么事,只是简单的调用了父类实现的那些方法而已。。。

  AbstractStringBuilder类:

  1. package java.lang;
  2.  
  3. import sun.misc.FloatingDecimal;
  4. import java.util.Arrays;
  5.  
  6. abstract class AbstractStringBuilder implements Appendable, CharSequence {
  7. //看来这个StringBuilder本质上也是一个字节数组,和String不同的是这里没有被final修饰
  8. char[] value;
  9.  
  10. //字符数组的容量
  11. int count;
  12.  
  13. AbstractStringBuilder() {
  14. }
  15.  
  16. //根据传进来的参数确定字符数组的大小
  17. AbstractStringBuilder(int capacity) {
  18. value = new char[capacity];
  19. }
  20.  
  21. //返回字符数组中实际数据的数量
  22. public int length() {
  23. return count;
  24. }
  25.  
  26. //返回字符数组的最大容量
  27. public int capacity() {
  28. return value.length;
  29. }
  30.  
  31. //一下三个方法都是确保那个字符数组大小足够而进行的扩容操作;首先判断你要确保新字节数组多大,
  32. //如果新数组容量比原来数组大,那么就进行扩容,扩容的时候还需要进行判断,比较系统自动扩容之后
  33. //的容量和你所确保的容量做个对比,如果系统扩容还达不到你的要求,那么新字节数组的大小就用你确保的那个容量吧
  34. //最后就是将原来数组中的数据复制到新的数组中
  35. public void ensureCapacity(int minimumCapacity) {
  36. if (minimumCapacity > 0)
  37. ensureCapacityInternal(minimumCapacity);
  38. }
  39.  
  40. private void ensureCapacityInternal(int minimumCapacity) {
  41.  
  42. if (minimumCapacity - value.length > 0)
  43. expandCapacity(minimumCapacity);
  44. }
  45.  
  46. void expandCapacity(int minimumCapacity) {
  47. int newCapacity = value.length * 2 + 2;
  48. if (newCapacity - minimumCapacity < 0)
  49. newCapacity = minimumCapacity;
  50. if (newCapacity < 0) {
  51. if (minimumCapacity < 0)
  52. throw new OutOfMemoryError();
  53. newCapacity = Integer.MAX_VALUE;
  54. }
  55. value = Arrays.copyOf(value, newCapacity);
  56. }
  57.  
  58. //去除数组中多余的位置;比如一个数组最大容量为5,但是实际放了3个数据,空出来两个位置,于是
  59. //可以将对于的两个空位置去掉(其实就是将那是那三个数据复制到一个新的数组中,然后改变value引用)
  60. public void trimToSize() {
  61. if (count < value.length) {
  62. value = Arrays.copyOf(value, count);
  63. }
  64. }
  65.  
  66. //设置字节数组的长度,多余的空位置添加'\0',这其实就是代表空字符,可以理解为null
  67. public void setLength(int newLength) {
  68. if (newLength < 0)
  69. throw new StringIndexOutOfBoundsException(newLength);
  70. ensureCapacityInternal(newLength);
  71.  
  72. if (count < newLength) {
  73. for (; count < newLength; count++)
  74. value[count] = '\0';
  75. } else {
  76. count = newLength;
  77. }
  78. }
  79.  
  80. //根据传进来的索引获取字节数组对应的数据
  81. public char charAt(int index) {
  82. if ((index < 0) || (index >= count))
  83. throw new StringIndexOutOfBoundsException(index);
  84. return value[index];
  85. }
  86.  
  87. //截取字节数组的连续的某几个字符,放到一个新的字节数组中
  88. public void getChars(int srcBegin, int srcEnd, char[] dst, int dstBegin)
  89. {
  90. if (srcBegin < 0)
  91. throw new StringIndexOutOfBoundsException(srcBegin);
  92. if ((srcEnd < 0) || (srcEnd > count))
  93. throw new StringIndexOutOfBoundsException(srcEnd);
  94. if (srcBegin > srcEnd)
  95. throw new StringIndexOutOfBoundsException("srcBegin > srcEnd");
  96. System.arraycopy(value, srcBegin, dst, dstBegin, srcEnd - srcBegin);
  97. }
  98.  
  99. //将字符数组某个位置的字符覆盖
  100. public void setCharAt(int index, char ch) {
  101. if ((index < 0) || (index >= count))
  102. throw new StringIndexOutOfBoundsException(index);
  103. value[index] = ch;
  104. }
  105.  
  106. //传入一个对象,将这个对象转化为字符串,然后将该字符串(就是一个字符数组)添加到当前字符数组的末尾
  107. //append方法就是在当前字符数组中后面添加所要添加的对象
  108. public AbstractStringBuilder append(Object obj) {
  109. return append(String.valueOf(obj));
  110. }
  111.  
  112. //首先要确保容量足够,再就是调用String类的getChars方法就是将传进去的str从0到最后,一次复制到value字节数组中
  113. public AbstractStringBuilder append(String str) {
  114. if (str == null) str = "null";
  115. int len = str.length();
  116. ensureCapacityInternal(count + len);
  117. str.getChars(0, len, value, count);
  118. count += len;
  119. return this;
  120. }
  121.  
  122. //将StringBuffer类型的字符字符数组复制到本类的字符数组中(首先要保证容量足够)
  123. public AbstractStringBuilder append(StringBuffer sb) {
  124. if (sb == null)
  125. return append("null");
  126. int len = sb.length();
  127. ensureCapacityInternal(count + len);
  128. sb.getChars(0, len, value, count);
  129. count += len;
  130. return this;
  131. }
  132.  
  133. //将一个字符数组的某一段复制到本类的字符数组当中
  134. public AbstractStringBuilder append(char str[], int offset, int len) {
  135. if (len > 0)
  136. ensureCapacityInternal(count + len);
  137. System.arraycopy(str, offset, value, count, len);
  138. count += len;
  139. return this;
  140. }
  141.  
  142. //在当前字符数组中添加boolean字符
  143. public AbstractStringBuilder append(boolean b) {
  144. if (b) {
  145. ensureCapacityInternal(count + 4);
  146. value[count++] = 't';
  147. value[count++] = 'r';
  148. value[count++] = 'u';
  149. value[count++] = 'e';
  150. } else {
  151. ensureCapacityInternal(count + 5);
  152. value[count++] = 'f';
  153. value[count++] = 'a';
  154. value[count++] = 'l';
  155. value[count++] = 's';
  156. value[count++] = 'e';
  157. }
  158. return this;
  159. }
  160.  
  161. //在当前字符数组最后中添加一个字符
  162. public AbstractStringBuilder append(char c) {
  163. ensureCapacityInternal(count + 1);
  164. value[count++] = c;
  165. return this;
  166. }
  167.  
  168. //在当前字符数组后面添加一个int类型(4个字节)的数据,要保证容量足够
  169. //后面还有添加各种数据类型long,double,float等省略
  170. public AbstractStringBuilder append(int i) {
  171. if (i == Integer.MIN_VALUE) {
  172. append("-2147483648");
  173. return this;
  174. }
  175. int appendedLength = (i < 0) ? Integer.stringSize(-i) + 1
  176. : Integer.stringSize(i);
  177. int spaceNeeded = count + appendedLength;
  178. ensureCapacityInternal(spaceNeeded);
  179. Integer.getChars(i, spaceNeeded, value);
  180. count = spaceNeeded;
  181. return this;
  182. }
  183.  
  184. //对一个字符数组中某一段进行删除,给出了起始位置和终点位置,可以看到就是利用的是数组的复制
  185. //重点System.arraycopy方法,可惜这是一个native方法,看不到源码
  186. public AbstractStringBuilder delete(int start, int end) {
  187. if (start < 0)
  188. throw new StringIndexOutOfBoundsException(start);
  189. if (end > count)
  190. end = count;
  191. if (start > end)
  192. throw new StringIndexOutOfBoundsException();
  193. int len = end - start;
  194. if (len > 0) {
  195. System.arraycopy(value, start+len, value, start, count-end);
  196. count -= len;
  197. }
  198. return this;
  199. }
  200.  
  201. //删除字符数组指定位置的字符
  202. public AbstractStringBuilder deleteCharAt(int index) {
  203. if ((index < 0) || (index >= count))
  204. throw new StringIndexOutOfBoundsException(index);
  205. System.arraycopy(value, index+1, value, index, count-index-1);
  206. count--;
  207. return this;
  208. }
  209.  
  210. //目的是为了让一个新的字符数组,代替本字符数组的某一段
  211. //其实还是通过数组的复制
  212. public AbstractStringBuilder replace(int start, int end, String str) {
  213. if (start < 0)
  214. throw new StringIndexOutOfBoundsException(start);
  215. if (start > count)
  216. throw new StringIndexOutOfBoundsException("start > length()");
  217. if (start > end)
  218. throw new StringIndexOutOfBoundsException("start > end");
  219.  
  220. if (end > count)
  221. end = count;
  222. int len = str.length();
  223. int newCount = count + len - (end - start);
  224. ensureCapacityInternal(newCount);
  225.  
  226. System.arraycopy(value, end, value, start + len, count - end);
  227. str.getChars(value, start);
  228. count = newCount;
  229. return this;
  230. }
  231.  
  232. //截取字符数组的某一段,其实就是新建了一个String类型的
  233. public String substring(int start, int end) {
  234. if (start < 0)
  235. throw new StringIndexOutOfBoundsException(start);
  236. if (end > count)
  237. throw new StringIndexOutOfBoundsException(end);
  238. if (start > end)
  239. throw new StringIndexOutOfBoundsException(end - start);
  240. return new String(value, start, end - start);
  241. }
  242.  
  243. //向StringBuilder中插入一个字节数组的某一段,省略好多的重载insert方法
  244. public AbstractStringBuilder insert(int index, char[] str, int offset,
  245. int len)
  246. {
  247. if ((index < 0) || (index > length()))
  248. throw new StringIndexOutOfBoundsException(index);
  249. if ((offset < 0) || (len < 0) || (offset > str.length - len))
  250. throw new StringIndexOutOfBoundsException(
  251. "offset " + offset + ", len " + len + ", str.length "
  252. + str.length);
  253. ensureCapacityInternal(count + len);
  254. System.arraycopy(value, index, value, index + len, count - index);
  255. System.arraycopy(str, offset, value, index, len);
  256. count += len;
  257. return this;
  258. }
  259.  
  260. //从前往后查看某个字符串的位置
  261. public int indexOf(String str) {
  262. return indexOf(str, 0);
  263. }
  264.  
  265. //从前往后其实就是调用String的indexof方法
  266. public int indexOf(String str, int fromIndex) {
  267. return String.indexOf(value, 0, count,
  268. str.toCharArray(), 0, str.length(), fromIndex);
  269. }
  270.  
  271. //从后往前找指定字符串的位置
  272. public int lastIndexOf(String str, int fromIndex) {
  273. return String.lastIndexOf(value, 0, count,
  274. str.toCharArray(), 0, str.length(), fromIndex);
  275. }
  276.  
  277. //逆序字符数组,实现很简单,不要看hasSurrogate了,反正我是没看懂这个boolean的。。。
  278. public AbstractStringBuilder reverse() {
  279. boolean hasSurrogate = false;
  280. int n = count - 1;
  281. for (int j = (n-1) >> 1; j >= 0; --j) {
  282. char temp = value[j];
  283. char temp2 = value[n - j];
  284. if (!hasSurrogate) {
  285. hasSurrogate = (temp >= Character.MIN_SURROGATE && temp <= Character.MAX_SURROGATE)
  286. || (temp2 >= Character.MIN_SURROGATE && temp2 <= Character.MAX_SURROGATE);
  287. }
  288. value[j] = temp2;
  289. value[n - j] = temp;
  290. }
  291. if (hasSurrogate) {
  292.  
  293. for (int i = 0; i < count - 1; i++) {
  294. char c2 = value[i];
  295. if (Character.isLowSurrogate(c2)) {
  296. char c1 = value[i + 1];
  297. if (Character.isHighSurrogate(c1)) {
  298. value[i++] = c1;
  299. value[i] = c2;
  300. }
  301. }
  302. }
  303. }
  304. return this;
  305. }
  306.  
  307. //留给子类实现,直接打印字符串
  308. public abstract String toString();
  309.  
  310. //返回字符数组
  311. final char[] getValue() {
  312. return value;
  313. }
  314.  
  315. }

  

  再看子类StringBuilder那就简单了:

  1. package java.lang;
  2.  
  3. //我们将这个父类看了一遍这里就简单多了,因为基本的方法父类都已经实现了,这里就是简单调用一下
  4. //我们就简单看看一些重要的方法
  5. public final class StringBuilder extends AbstractStringBuilder
  6. implements java.io.Serializable, CharSequence
  7. {
  8. //初始化字符数组的大小
  9. public StringBuilder() {
  10. super(16);
  11. }
  12.  
  13. //也可以自定义字符数组的大小
  14. public StringBuilder(int capacity) {
  15. super(capacity);
  16. }
  17.  
  18. //初始化一个字符串的时候,我们会先创建一个比字符串大16的一个字符数组,然后将字符串添加进去
  19. public StringBuilder(String str) {
  20. super(str.length() + 16);
  21. append(str);
  22. }
  23.  
  24. //没有做什么事,就是简单的调用的一下父类的方法
  25. public StringBuilder append(Object obj) {
  26. return append(String.valueOf(obj));
  27. }
  28. public StringBuilder append(String str) {
  29. super.append(str);
  30. return this;
  31. }
  32.  
  33. //扩展一以下,可以在后面添加StringBuilder类型的数据
  34. private StringBuilder append(StringBuilder sb) {
  35. if (sb == null)
  36. return append("null");
  37. int len = sb.length();
  38. int newcount = count + len;
  39. if (newcount > value.length)
  40. expandCapacity(newcount);
  41. sb.getChars(0, len, value, count);
  42. count = newcount;
  43. return this;
  44. }
  45.  
  46. //下面省略一堆append方法,就是简单的调用父类的append的各种重载方法
  47. //还省略一些知识简单的调用父类方法的这种无聊的方法。。。
  48.  
  49. //实现父类的toString方法,返回一个字符串
  50. public String toString() {
  51.  
  52. return new String(value, 0, count);
  53. }
  54.  
  55. //下面这两个方法挺有意思的,这两个方法是本类独有的,可以传入io流,将数据写入到字节数组中或者从字节数组中读取数据
  56. private void writeObject(java.io.ObjectOutputStream s)
  57. throws java.io.IOException {
  58. s.defaultWriteObject();
  59. s.writeInt(count);
  60. s.writeObject(value);
  61. }
  62.  
  63. private void readObject(java.io.ObjectInputStream s)
  64. throws java.io.IOException, ClassNotFoundException {
  65. s.defaultReadObject();
  66. count = s.readInt();
  67. value = (char[]) s.readObject();
  68. }
  69.  
  70. }

  

  有没有发现,StringBuilder类和String类一样是被final修饰了的,是属于不可变的,关于final关键字修饰的知识,大概提一下,不可变指的是引用不可变,内容可以变,例如下面代码:

  1. StringBuilder name = new StringBuilder("java小新人");
  2. final StringBuilder str = name;
  3.  
  4. name.append("hello");
  5. System.out.println(str); //java小新人hello
  6.  
  7. str = "world";//这里编译器会报错

  随意提一下StringBuffer类,我们看看这个类:final class StringBuffer extends AbstractStringBuilder,居然也是继承了AbstractStringBuilder这个类,那么可以知道内部方法和StringBuilder一模一样,那么有什么区别呢?随便看一个StringBuffer中的简单的方法,如下所示;

  很清楚的看到有个synchronized关键字,这个关键字就涉及到多线程的时候,同一时刻只有一个线程能够访问这个方法,想详细了解synchronized关键字用法的可以看看我之前的博客,或者自己看看资料也行。。。

5.总结

  自己看看源码还是很有必要的,我总是感觉要行框架中走出来,基础始终都是基础,我们只有把基础搞的扎实了,学java就很容易了!

  也许我的这种看源码的方式不适合你,但是作为一个参考,你也可以自己去看看源码了,对了,当我们去复制一个java源码中的一个类的时候,会发现注释的代码很多,那有没有办法可以直接删除所有注释呢?找了好久找到了一个java小脚本,只需要修改一下目录名称就好了。。。

  1. import java.io.BufferedReader;
  2. import java.io.BufferedWriter;
  3. import java.io.File;
  4. import java.io.FileInputStream;
  5. import java.io.FileOutputStream;
  6. import java.io.InputStreamReader;
  7. import java.io.OutputStreamWriter;
  8.  
  9. public class Delete {
  10.  
  11. private static int count = 0;
  12.  
  13. /**
  14. * 删除文件中的各种注释,包含//、/* * /等
  15. * @param charset 文件编码
  16. * @param file 文件
  17. */
  18. public static void clearComment(File file, String charset) {
  19. try {
  20. //递归处理文件夹
  21. if (!file.exists()) {
  22. return;
  23. }
  24.  
  25. if (file.isDirectory()) {
  26. File[] files = file.listFiles();
  27. for (File f : files) {
  28. clearComment(f, charset); //递归调用
  29. }
  30. return;
  31. } else if (!file.getName().endsWith(".java")) {
  32. //非java文件直接返回
  33. return;
  34. }
  35. System.out.println("-----开始处理文件:" + file.getAbsolutePath());
  36.  
  37. //根据对应的编码格式读取
  38. BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(file), charset));
  39. StringBuffer content = new StringBuffer();
  40. String tmp = null;
  41. while ((tmp = reader.readLine()) != null) {
  42. content.append(tmp);
  43. content.append("\n");
  44. }
  45. String target = content.toString();
  46. //String s = target.replaceAll("\\/\\/[^\\n]*|\\/\\*([^\\*^\\/]*|[\\*^\\/*]*|[^\\**\\/]*)*\\*\\/", ""); //本段正则摘自网上,有一种情况无法满足(/* ...**/),略作修改
  47. String s = target.replaceAll("\\/\\/[^\\n]*|\\/\\*([^\\*^\\/]*|[\\*^\\/*]*|[^\\**\\/]*)*\\*+\\/", "");
  48. //System.out.println(s);
  49. //使用对应的编码格式输出
  50. BufferedWriter out = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(file), charset));
  51. out.write(s);
  52. out.flush();
  53. out.close();
  54. count++;
  55. System.out.println("-----文件处理完成---" + count);
  56. } catch (Exception e) {
  57. e.printStackTrace();
  58. }
  59. }
  60.  
  61. public static void clearComment(String filePath, String charset) {
  62. clearComment(new File(filePath), charset);
  63. }
  64.  
  65. public static void clearComment(String filePath) {
  66. clearComment(new File(filePath), "UTF-8");
  67. }
  68.  
  69. public static void clearComment(File file) {
  70. clearComment(file, "UTF-8");
  71. }
  72.  
  73. public static void main(String[] args) {
  74. clearComment("C:\\Users\\asus\\Desktop\\jdk源码文件\\03.java"); //删除目录下所有java文件注释
  75. //删除某个具体文件的注释
  76. //clearComment("D:\\proj\\scm\\action\\AbcdefgAction.java");
  77. }
  78.  
  79. }

  后续的还会慢慢的看jdk源码的,最好是一遍看的时候有的方法可以敲敲代码试试!

简单看看jdk7源码之java.lang包01的更多相关文章

  1. JDK1.8源码(二)——java.lang.Integer 类

    上一篇博客我们介绍了 java.lang 包下的 Object 类,那么本篇博客接着介绍该包下的另一个类 Integer.在前面 浅谈 Integer 类 博客中我们主要介绍了 Integer 类 和 ...

  2. JDK1.8源码(三)——java.lang.String 类

    String 类也是java.lang 包下的一个类,算是日常编码中最常用的一个类了,那么本篇博客就来详细的介绍 String 类. 1.String 类的定义 public final class ...

  3. JDK1.8源码(一)——java.lang.Object类

    本系列博客将对JDK1.8版本的相关类从源码层次进行介绍,JDK8的下载地址. 首先介绍JDK中所有类的基类——java.lang.Object. Object 类属于 java.lang 包,此包下 ...

  4. JDK1.7.0_45源码阅读<java.lang.Boolean>

    本文适合的人群 其实感觉写这个标题的内容没有必要,只要你觉得对你有帮助那么就适合你,对你没帮助那么就不适合你.毕竟我不是专业作者,但咱会尽力的.其实最重要的一点是我不希望浪费您宝贵时间. 简要把内容在 ...

  5. Java源码学习 -- java.lang.StringBuilder,java.lang.StringBuffer,java.lang.AbstractStringBuilder

    一直以来,都是看到网上说“ StringBuilder是线程不安全的,但运行效率高:StringBuffer 是线程安全的,但运行效率低”,然后默默记住:一个是线程安全.一个线程不安全,但对内在原因并 ...

  6. 从源码分析java.lang.String.isEmpty()

    今天在写代码的时候用到了java.lang.String.isEmpty()的这个方法,之前也用过,今天突发奇想,就看了看源码,了解了解它的实现方法,总结出来,大家可以交流交流. 通常情况下,我们使用 ...

  7. Java 源码赏析 - java.lang - Void

    被人鄙视了,于是也来读读源码... package java.lang; /** * The Void class is an uninstantiable placeholder class to ...

  8. JDK1.8源码(二)——java.lang.Integer类

    一.初识 1.介绍 int 是Java八大基本数据类型之一,占据 4 个字节,范围是 -2^31~2^31 - 1,即 -2147483648~2147483647.而 Integer 是 int 包 ...

  9. JDK1.8源码(三)——java.lang.String类

    一.概述 1.介绍 String是一个final类,不可被继承,代表不可变的字符序列,是一个类类型的变量.Java程序中的所有字符串字面量(如"abc")都作为此类的实例实现,&q ...

随机推荐

  1. Object-c学习笔记(1)

    说明:本人用的win8 系统装Code::Blocks练习OC. 1.类的声明和实现的关系图:  @interface就好像暴露在外面的时钟表面  @implementation就好像隐藏在时钟内部的 ...

  2. QWidget 之paint部分杂记(从Qt4.0到4.8的进化,在Qt 4.4中,Alien Widget诞生了)

    Qt 4.0 automatically double-buffers Qt 4.1 QWidget::autoFillBackground Qt 4.2 delayed widget creatio ...

  3. thread、Task、async & await

    学习 Jesse 的文章 async & await 的前世今生(Updated) 而来 Thread是最开始使用的多线程.new一个Thread对象,将方法传进去.手动Start() 还可以 ...

  4. 简明Python3教程 19.附录 FLOSS

    FLOSS Free/Libre and Open Source Software, in short, FLOSS is based on the concept of a community, w ...

  5. WPF 3D 获取鼠标在场景的3d坐标

    原文:WPF 3D 获取鼠标在场景的3d坐标 上一篇中我们谈到了WPF 3d做图的一些简单原理,这里我们简单介绍一下怎样获得鼠标在场景中的3d坐标,知道了3d坐标就可以进行很多操作了: 首先介绍一下3 ...

  6. VxWorks启动过程的详细解释(上)

    vxworks有三个图像: VxWorks Image有三种类型的文件 Loadable Images:由Boot-ROM引导通过网口或串口下载到RAM ROM-based Images(压缩/没有压 ...

  7. WPF 把图片分割成两份自动翻页 WpfFlipPageControl:CtrlBook 书控件

    原文:WPF 把图片分割成两份自动翻页 WpfFlipPageControl:CtrlBook 书控件 版权声明:本文为博主原创文章,需要转载尽管转载. https://blog.csdn.net/z ...

  8. WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式

    原文:WPF中实现PropertyGrid(用于展示对象的详细信息)的三种方式 由于WPF中没有提供PropertyGrid控件,有些业务需要此类的控件.这篇文章介绍在WPF中实现PropertyGr ...

  9. zend-form笔记

    Zend-Form组件包含以下几个对象: 1.Elements:包含了name和attributes, 2.Fieldsets:继承自elements,但允许包含其他fieldset和elements ...

  10. OnPropertyChanged的使用

    #region INotifyPropertyChanged         public event PropertyChangedEventHandler PropertyChanged;     ...