String源码解析

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的字符复制给value
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);
     }

//将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());
        }
    }
//参数为StringBuilder
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值