String源码解析

来源:互联网 发布:ubuntu安装完重启黑屏 编辑:程序博客网 时间:2024/05/17 09:19

String源码解析


1、String类

String为final类,所以String为不可变量,String类还实现了Serializable,Comparable,CharSequence接口。
Comparable接口有compareTo(String s)方法。
CharSequence接口有length(),charAt(int index),subSequence(int start,int end)方法。

String类中有一个final的char数组用来存放字符串,一个int类型的hash用来存放哈希值。

2、构造方法

//不含参数,基本没用public String() {        this.value = new char[0];}//参数为String类型public String(String original) {         this.value = original.value;         this.hash = original.hash;}//参数为char数组,使用Arrays.copyOf()给value复制public String(char value[]) {         this.value = Arrays.copyOf(value, value.length);     }//将char数组从offset开始的长度为length的字符复制给valuepublic 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);     }//将int数组从offset开始的长度为length的数据转型为字符复制给value  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;}public String(byte ascii[], int hibyte, int offset, int count) {        //检查是否越界         checkBounds(ascii, offset, count);         char value[] = new char[count];         if (hibyte == 0) {             for (int i = count; i-- > 0;) {                 value[i] = (char)(ascii[i + offset] & 0xff);             }         } else {             hibyte <<= 8;             for (int i = count; i-- > 0;) {                 value[i] = (char)(hibyte | (ascii[i + offset] & 0xff));            }         }         this.value = value;     }//从bytes数组中的offset位置开始,将长度为length的字节,以charsetName格式编码,拷贝到value public String(byte bytes[], int offset, int length, String charsetName)             throws UnsupportedEncodingException {         if (charsetName == null)             throw new NullPointerException("charsetName");         checkBounds(bytes, offset, length);         this.value = StringCoding.decode(charsetName, bytes, offset, length);     }//参数为StringBuffer(线程安全)public String(StringBuffer buffer) {         synchronized(buffer) {            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());        }    }//参数为StringBuilderpublic String(StringBuilder builder) {         this.value = Arrays.copyOf(builder.getValue(), builder.length());    }

3、String常用方法

length()

public int length() {         return value.length;     }

isEmpty()

 public boolean isEmpty() {         return value.length == 0;     }

equals(Object o)

 public boolean equals(Object anObject) {        //是否同一对象         if (this == anObject) {             return true;         }         //是否为String类型数据         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;     }
public int compareTo(String anotherString) {        int len1 = value.length;        int len2 = anotherString.value.length;        //取长度最小值        int lim = Math.min(len1, len2);        char v1[] = value;        char v2[] = anotherString.value;        int k = 0;        //从前往后直到第lim个进行比较        while (k < lim) {            char c1 = v1[k];            char c2 = v2[k];            if (c1 != c2) {                return c1 - c2;            }            k++;     }       //相同则比较长度        return len1 - len2;    }

hashCode()

public int hashCode() {        int h = hash;        //hash是否计算过        if (h == 0 && value.length > 0) {            char val[] = value;            for (int i = 0; i < value.length; i++) {                h = 31 * h + val[i];            }            //给hash赋值            hash = h;        }        return h;    }

concat(String s)

 public String concat(String str) {        int otherLen = str.length();        if (otherLen == 0) {            return this;        }        int len = value.length;        char buf[] = Arrays.copyOf(value, len + otherLen);        str.getChars(buf, len);        return new String(buf, true);    }

trim()

public String trim() {        int len = value.length;        int st = 0;        char[] val = value;    /* avoid getfield opcode */        while ((st < len) && (val[st] <= ' ')) {            st++;        }        while ((st < len) && (val[len - 1] <= ' ')) {            len--;        }        return ((st > 0) || (len < value.length)) ? substring(st, len) : this;    }

intern方法是Native调用,它的作用是在方法区中的常量池里通过equals方法寻找等值的对象,如果没有找到则在常量池中开辟一片空间存放字符串并返回该对应String的引用,否则直接返回常量池中已存在String对象的引用。

 public native String intern();
0 0
原创粉丝点击