Java String源码之类声明与构造函数(二)

来源:互联网 发布:詹姆斯数据历史排名 编辑:程序博客网 时间:2024/05/17 23:42

Java String 源码

继续看String源码:

// 按照指定编码,生成新字符串public String(byte bytes[], int offset, int length, String charsetName)            throws UnsupportedEncodingException {        if (charsetName == null)            throw new NullPointerException("charsetName");            // 检查byte数组的合法性        checkBounds(bytes, offset, length);        this.value = StringCoding.decode(charsetName, bytes, offset, length);    } // 检查byte数组, 传入length 不能为负数,偏移量offset 不能为负,偏移量不能越界private static void checkBounds(byte[] bytes, int offset, int length) {        if (length < 0)            throw new StringIndexOutOfBoundsException(length);        if (offset < 0)            throw new StringIndexOutOfBoundsException(offset);        if (offset > bytes.length - length)            throw new StringIndexOutOfBoundsException(offset + length);    }// 再来看 static char[] decode(String charsetName, byte[] ba, int off, int len)        throws UnsupportedEncodingException    {        StringDecoder sd = deref(decoder);        String csn = (charsetName == null) ? "ISO-8859-1" : charsetName;        if ((sd == null) || !(csn.equals(sd.requestedCharsetName())                              || csn.equals(sd.charsetName()))) {            sd = null;            try {                Charset cs = lookupCharset(csn);                if (cs != null)                    sd = new StringDecoder(cs, csn);            } catch (IllegalCharsetNameException x) {}            if (sd == null)                throw new UnsupportedEncodingException(csn);            set(decoder, sd);        }        // 主要是一些编码的存取,最后返回sd.decode方法来处理        return sd.decode(ba, off, len);    }// 这个方法主要最终调用了safeTrim方法,用户拷贝新的byte数组char[] decode(byte[] ba, int off, int len) {            int en = scale(len, cd.maxCharsPerByte());            char[] ca = new char[en];            if (len == 0)                return ca;            if (cd instanceof ArrayDecoder) {                int clen = ((ArrayDecoder)cd).decode(ba, off, len, ca);                return safeTrim(ca, clen, cs, isTrusted);            } else {                cd.reset();                ByteBuffer bb = ByteBuffer.wrap(ba, off, len);                CharBuffer cb = CharBuffer.wrap(ca);                try {                    CoderResult cr = cd.decode(bb, cb, true);                    if (!cr.isUnderflow())                        cr.throwException();                    cr = cd.flush(cb);                    if (!cr.isUnderflow())                        cr.throwException();                } catch (CharacterCodingException x) {                    // Substitution is always enabled,                    // so this shouldn't happen                    throw new Error(x);                }                return safeTrim(ca, cb.position(), cs, isTrusted);            }        }private static char[] safeTrim(char[] ca, int len,                                   Charset cs, boolean isTrusted) {        if (len == ca.length && (isTrusted || System.getSecurityManager() == null))            return ca;        else            return Arrays.copyOf(ca, len);    }

再来看接下来的构造方法:
方法都是最终调用了上面那个方法.

public String(byte bytes[], int offset, int length, Charset charset) {        if (charset == null)            throw new NullPointerException("charset");        checkBounds(bytes, offset, length);        this.value =  StringCoding.decode(charset, bytes, offset, length);    }public String(byte bytes[], String charsetName)            throws UnsupportedEncodingException {        this(bytes, 0, bytes.length, charsetName);    }public String(byte bytes[], Charset charset) {        this(bytes, 0, bytes.length, charset);    }public String(byte bytes[], int offset, int length) {        checkBounds(bytes, offset, length);        this.value = StringCoding.decode(bytes, offset, length);    }public String(byte bytes[]) {        this(bytes, 0, bytes.length);    }

接下来是SringBuffer\StringBuilder

// 构造方法参数加锁,实现线程安全 public String(StringBuffer buffer) {        synchronized(buffer) {            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());        }    }// StringBuilder生成新的String,非线程安全 public String(StringBuilder builder) {        this.value = Arrays.copyOf(builder.getValue(), builder.length());    }

继续看:

/*    * Package private constructor which shares value array for speed.    * this constructor is always expected to be called with share==true.    * a separate constructor is needed because we already have a public    * String(char[]) constructor that makes a copy of the given char[].    */// 注释里已经说明, always expected to be called with share==true., 希望每次share 都是 true, 就是实现复制char[]    String(char[] value, boolean share) {        // assert share : "unshared not supported";        this.value = value;    }
原创粉丝点击