[java源码分析项目]第一周

作业一——native关键字]

http://www.blogjava.net/shiliqiang/articles/287920.html
由于没有实际使用过,就了解后转载来了事了。

String ()源码分析

签名(signature)

public final class  String
   implements java.io.Serializable, Comparable<String>, CharSequence {

所有已实现的接口:

Serializable——可序列化
CharSequence——是 char 值的一个可读序列。此接口对许多不同种类的 char 序列提供统一的只读访问。
Comparable——此接口强行对实现它的每个类的对象进行整体排序。此排序被称为该类的自然排序,类的 compareTo 方法被称为它的自然比较方法。

设计理念

本质:姑且理解为char[]
原因:
有成员变量 private final char value[];
构造函数以char[] 为参数时,直接copy,并没有进行编码coding,而是直接复制了事。

   public String(char value[]) {
         this.value = Arrays.copyOf(value, value.length);
    }

与char[]的不同点:

源码剖析

成员变量

private final char value[];
hash
//Cache the hash code for the string
 创建hash code
 private int hash; // Default to 0


use serialVersionUID from JDK 1.0.2 for interoperability
serialversionUID

不明觉厉的变量,直接copy了 = =
http://www.cnblogs.com/guanghuiqq/archive/2012/07/18/2597036.html
private static final long serialVersionUID = -6849794470754667710L;

Class String is special cased within the Serialization Stream Protocol. A String instance is written initially into an ObjectOutputStream in the following format:
      TC_STRING (utf String)

The String is written by method DataOutput.writeUTF. A new handle is generated to refer to all future references to the string instance within the stream.
ObjectStreamField[]
 private static final ObjectStreamField[] serialPersistentFields =
         new ObjectStreamField[0];


Initializes a newly created String object so that it represents an empty character sequence. Note that use of this constructor is unnecessary since Strings are immutable.

方法

构造方法:
String()

139 public More …String() {
140 this.value = new char[0];
141 }

String (char value[])
 public More ...String(char value[]) {
     this.value = Arrays.copyOf(value, value.length);
}
其他方法:
public byte[] getBytes()
 public byte[] More ...getBytes() {         
     return StringCoding.encode(value, 0, value.length);    
  }

StringCoding:???什么鬼????
Utility class for string encoding and decoding——负责String编码/解码的工具类

StringCoding.encode代码奉上

  static byte[] More ...encode(char[] ca, int off, int len) {
    String csn = Charset.defaultCharset().name();
   try {
  // use charset name encode() variant which provides caching.
        return encode(csn, ca, off, len);
    } catch (UnsupportedEncodingException x) {
        warnUnsupportedCharset(csn);
    }
    try {
        return encode("ISO-8859-1", ca, off, len);//编码表
    } catch (UnsupportedEncodingException x) {
        // If this code is hit during VM initialization, MessageUtils is
        // the only way we will be able to get any kind of error message.
       MessageUtils.err("ISO-8859-1 charset not available: "
                         + x.toString());
        // If we can not find ISO-8859-1 (a required encoding) then things
        // are seriously wrong with the installation.
        System.exit(1);
        return null;
    }
  }
}

最后它返回了一个byte[]。。。。
为了不跑题,且先放弃。实际上是干不下去了。。。

getChars()
void getChars(char dst[], int dstBegin) {
  System.arraycopy(value, 0, dst, dstBegin, value.length);
}

复制char到一个目标数组中。

getChars和getBytes的区别:

getBytes需要String解码,而另一个则不需要。——故而想到构建String时char[]是直接用Arrays.copy拷贝到成员变量上。

arraycopy的源码
 public static native void arraycopy(Object src,  int  srcPos,
                                    Object dest, int destPos,
                                   int length);

分析:
Copies an array from the specified source array, beginning at the specified position, to the specified position of the destination array. A subsequence of array components are copied from the source array referenced by src to the destination array referenced by dest. The number of components copied is equal to the length argument. The components at positions srcPos through srcPos+length-1 in the source array are copied into positions destPos through destPos+length-1, respectively, of the destination array.
If the src and dest arguments refer to the same array object, then the copying is performed as if the components at positions srcPos through srcPos+length-1 were first copied to a temporary array with length components and then the contents of the temporary array were copied into positions destPos through destPos+length-1 of the destination array.
If dest is null, then a NullPointerException is thrown.
If src is null, then a NullPointerException is thrown and the destination array is not modified.
Otherwise, if any of the following is true, an ArrayStoreException is thrown and the destination is not modified:
The src argument refers to an object that is not an array.
The dest argument refers to an object that is not an array.
The src argument and dest argument refer to arrays whose component types are different primitive types.
The src argument refers to an array with a primitive component type and the dest argument refers to an array with a reference component type.
The src argument refers to an array with a reference component type and the dest argument refers to an array with a primitive component type.
Otherwise, if any of the following is true, an IndexOutOfBoundsException is thrown and the destination is not modified:
The srcPos argument is negative.
The destPos argument is negative.
The length argument is negative.
srcPos+length is greater than src.length, the length of the source array.
destPos+length is greater than dest.length, the length of the destination array.
Otherwise, if any actual component of the source array from position srcPos through srcPos+length-1 cannot be converted to the component type of the destination array by assignment conversion, an ArrayStoreException is thrown. In this case, let k be the smallest nonnegative integer less than length such that src[srcPos+k] cannot be converted to the component type of the destination array; when the exception is thrown, source array components from positions srcPos through srcPos+k-1 will already have been copied to destination array positions destPos through destPos+k-1 and no other positions of the destination array will have been modified. (Because of the restrictions already itemized, this paragraph effectively applies only to the situation where both arrays have component types that are reference types.)
Parameters:
src the source array.
srcPos starting position in the source array.
dest the destination array.
destPos starting position in the destination data.
length the number of array elements to be copied.
Throws:
IndexOutOfBoundsException if copying would cause access of data outside array bounds.
ArrayStoreException if an element in the src array could not be stored into the dest array because of a type mismatch.
NullPointerException if either src or dest is null.

toCharArray()
public char[] toCharArray() {
    // Cannot use Arrays.copyOf because of class initialization order issues
    char result[] = new char[value.length];
    System.arraycopy(value, 0, result, 0, value.length);
    return result;
}

作用:生成一个char[] 包含String的所有字符
问题:与getChars()的区别?
实现上没有什么特别大的差别。前者是全部,后者是指定一段的

charAt(int)方法
 public char  charAt(int index) {
     if ((index < 0) || (index >= value.length)) {
         throw new StringIndexOutOfBoundsException(index);
     }
     return value[index];
 }

返回一点的char值,因为感觉string本质是char[],所以并没有什么好分析的

这是String类里的一段源码。它override了java.lang.CharSequence接口中的charAt(int).

equals(Object)

源码:

public boolean equals(Object anObject) {
         if (this == anObject) {
        return true;
     }
     if (anObject instanceof String) {
         String anotherString = (String) anObject;
         int n = value.length;
         if (n == anotherString.value.length) {
             char v1[] = value;
             char v2[] = anotherString.value;
             int i = 0;
             while (n-- != 0) {
                 if (v1[i] != v2[i])
                         return false;
                 i++;
             }
             return true;
         }
     }
     return false;
 }

第一步:分析是不是是不是handle指向同一块内存
第二步:分析对象是不是属于String类,如果是,就强制转换成char[],进行逐个比较分析,如果不是,就错!

equalsIgnreCase(String anotherString)
public boolean equalsIgnoreCase(String anotherString) {        return (this == anotherString) ? true   :(anotherString != null)
            && (anotherString.value.length == value.length)                && regionMatches(true, 0, anotherString, 0, value.length);    }

忽略大小写,如果两个一致,就ok!
步骤,先分析两个是不是在同一个内存上。如果是则正确,不是则分析两个是不是空,长度是否相等,还有用了一个regionMatches方法。
regionMatches方法:
代码:——它也是String的一部分
1323
1324 public boolean regionMatches(boolean ignoreCase, int toffset,
1325 String other, int ooffset, int len) {
1326 char ta[] = value;
1327 int to = toffset;
1328 char pa[] = other.value;
1329 int po = ooffset;
1330 // Note: toffset, ooffset, or len might be near -1>>>1.
1331 if ((ooffset < 0) || (toffset < 0)
1332 || (toffset > (long)value.length - len)
1333 || (ooffset > (long)other.value.length - len)) {
1334 return false;
1335 }
1336 while (len– > 0) {
1337 char c1 = ta[to++];
1338 char c2 = pa[po++];
1339 if (c1 == c2) {
1340 continue;
1341 }
1342 if (ignoreCase) {
1343 // If characters don’t match but case may be ignored,
1344 // try converting both characters to uppercase.
1345 // If the results match, then the comparison scan should
1346 // continue.
1347 char u1 = Character.toUpperCase(c1);
1348 char u2 = Character.toUpperCase(c2);
1349 if (u1 == u2) {
1350 continue;
1351 }
1352 // Unfortunately, conversion to uppercase does not work properly
1353 // for the Georgian alphabet, which has strange rules about case
1354 // conversion. So we need to make one last check before
1355 // exiting.
1356 if (Character.toLowerCase(u1) == Character.toLowerCase(u2)) {
1357 continue;
1358 }
1359 }
1360 return false;
1361 }
1362 return true;
1363 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值