JDK1.6 源码学习笔记

来源:互联网 发布:淘宝c2c模式分析 编辑:程序博客网 时间:2024/05/18 22:46

为了进一步的提高自己的技术水平,开始阅读和学习Java源码。
为了能和大家互相学习和交流,今天决定将自己的学习笔记发布到blog上。
一来,作为自己学习的记录;
二来,也希望可以和大家一起交流学习。

本人能力有限,如有错误的地方,请大家批评指正,更希望大家可以帮助我解决一些在学习中的疑难问题(疑难问题会在每节笔记的最后提出来,欢迎大家一起讨论)。


源码学习JDK版本:JDK1.6


第一节:java.lang.String

1.String在内部是以字符数组的形式存放的

private final char value[];

并且通过起始坐标和大小来定义表示的字符串

private final int offset;private final int count;

2.Strings are constant.

  java中的String是"常量"的形式,在被创建后,是不能被改变的,个人理解成String是一种共享的状态。

String str1 = "abc";String str2 = "abc";

在内存中,只有一个"abc",str1和str2都是指向这个唯一的"abc"的地址。

这一点有可以通过String的构造方法进一步确认。

public String(String original) {int size = original.count;char[] originalValue = original.value;char[] v;  if (originalValue.length > size) {     // The array representing the String is bigger than the new     // String itself.  Perhaps this constructor is being called     // in order to trim the baggage, so make a copy of the array.            int off = original.offset;            v = Arrays.copyOfRange(originalValue, off, off+size); } else {     // The array representing the String is the same     // size as the String, so no point in making a copy.    v = originalValue; }this.offset = 0;this.count = size;this.value = v;    }
可以从构造方法看出,在新建一个String时,只有当参数中字符串value的长度大于传入的参数长度count时,才会调用Arrays.copyOfRange来新建一个新的String的实例,从而产生一个指向此字符的新地址;否则新String中的字符数组将指向传入的String的字符数组的坐标,两者共享此字符,而不会去新增一个实例。
但是,针对通过char[]形式新建的字符串则不同,系统会copy一份char[]复制给String对象,这一点可以从String的另外一个构造方法看出:
public String(char value[]) {this.offset = 0;this.count = value.length;this.value = StringValue.from(value);    }
StringValue.from(value)方法将会调用Arrays.copyOf(),从而在新的地址上产生一个新的char[]。
另外,String内部存放的char value[]也是无法直接得到的,这一点可以从String的方法getChars()看出来。getChars()方法,每次都是返回String内部的字符串数组的一个copy,而不是String自己的char[]。
这也可以验证上面说的"String在被创建后,是不能直接被改变的"。
void getChars(char dst[], int dstBegin) {        System.arraycopy(value, offset, dst, dstBegin, count);    }public void getChars(int srcBegin, int srcEnd, char dst[], int dstBegin) {        if (srcBegin < 0) {            throw new StringIndexOutOfBoundsException(srcBegin);        }        if (srcEnd > count) {            throw new StringIndexOutOfBoundsException(srcEnd);        }        if (srcBegin > srcEnd) {            throw new StringIndexOutOfBoundsException(srcEnd - srcBegin);        }        System.arraycopy(value, offset + srcBegin, dst, dstBegin,             srcEnd - srcBegin);    }


PS:

Arrays.copyOf()和Arrays.copyOfRange()方法都将会调用底层的System.arraycopy()来复制一份新的数组。


疑问1:

char data[] = {'a', 'b', 'c'};String str = new String(data); 

如果改变data,str是否也会改变?

个人作答:改变data,不会引起str的改变。因为new String(data)将会使用构造方法public String(char value[]){},而此构造方法将会copy一个新的char[]。


疑问2:

String str1 = "abc";String str2 = str1;String str3 = new String(str1);

此处str1、str2、str3按道理,他们的属性char[] value对应的值应该是一样(内存地址引用一样),但是不知道该如何去验证,希望知道的朋友指点一下,谢谢。


本人的第一篇JDK源码阅读的文章到此结束,希望大家指出其中的不足(包括源码解读的错误,也包括blog文章的建议)。

另外,如果大家有兴趣转载,请注明原文出处,谢谢!


原创粉丝点击