java包装类之String类源码分析

String类是一个字符串的包装类,下面我来给大家分析一下String类的源码。

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

可以看到String类是一个final类,不可以用来继承,Serializable接口(可序列化接口),Comparable<String>接口(泛型为String类型的比较器接口),CharSequence接口(char值的可读序列接口)。

下面是四个全局私有变量和常量:

/** 最终char类型数组 */
    private final char value[];

    /** hash值 */
    private int hash; // Default to 0

    /** 最终序列化值 */
    private static final long serialVersionUID = -6849794470754667710L;

    /**串行化字段数组*/
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

无参构造:

 public String() {
        this.value = "".value;
 }

初始化构造函数:

 public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
 }

char类型数组构造:

public String(char value[]) {
        //复制value数组到this.value数组中
        this.value = Arrays.copyOf(value, value.length);
}

多参数构造:

public String(char value[], int offset, int count) {
        if (offset < 0) {
            //如果offset小于0抛出字符串角标越界异常
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
             //如果count的值小于0抛出字符串角标越界异常
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
             //如果offset小于等于value数组的长度,this.value的值为空字符串的value值
                this.value = "".value;
             //返回
                return;
            }
        }
        // 如果offset的值大于value数组的长度减去总数
        if (offset > value.length - count) {
        // 抛出字符串角标越界异常
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        //截取角标从offset到offset+count的数组到this.value的数组
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }
public String(int[] codePoints, int offset, int count) {
        if (offset < 0) {
            //如果offset小于0抛出字符串角标越界异常
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
            //如果count小于0抛出字符串角标越界异常
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= codePoints.length) {
                //空字符的值赋值给this.value
                this.value = "".value;
                //返回
                return;
            }
        }
        // 如果offset大于codePoints的长度减去count
        if (offset > codePoints.length - count) {
            //抛出字符串角标越界异常
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        
        //最终变量 end值等于offset的值加上count的值
        final int end = offset + count;

        // count的值赋值给变量n
        int n = count;
        //循环 offset赋值给i,i小于end,i自增
        for (int i = offset; i < end; i++) {
            //把codePoints数组中角标为i的值赋值给int变量c
            int c = codePoints[i];
            //如果c字符在bmp中
            if (Character.isBmpCodePoint(c))
            //循环继续
                continue;
            //如果字符c是一个有效的Unicode值
            else if (Character.isValidCodePoint(c))
            //n自增
                n++;
            //否则抛出非法参数异常
            else throw new IllegalArgumentException(Integer.toString(c));
        }

        // Pass 2: Allocate and fill in char[]
            //new一个最终字符数组
        final char[] v = new char[n];
            //循环i等于offset j等于0 i小于end  i自增 j自增
        for (int i = offset, j = 0; i < end; i++, j++) {
            //codePoints数组角标为i的值赋值给int类型变量c
            int c = codePoints[i];
            //如果变量c在bmp中
            if (Character.isBmpCodePoint(c))
            //变量c强转成char类型并且赋值给v数组中角标为j的值中
                v[j] = (char)c;
            else
            //
                Character.toSurrogates(c, v, j++);
        }

        this.value = v;
    }


    /* 
     *检查offset,count参数在字节数组中是否越界的工具方法 
     *Common private utility method used to bounds check the byte array
     * and requested offset & length values used by the String(byte[],..)
     * constructors.
     */
    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);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照指定的字符集编码 
     * 解码为一个字符串对象 
     * Constructs a new {@code String} by decoding the specified subarray of
     * bytes using the specified charset.  The length of the new {@code String}
     * is a function of the charset, and hence may not be equal to the length
     * of the subarray.
     *
     * <p> The behavior of this constructor when the given bytes are not valid
     * in the given charset is unspecified.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  offset
     *         The index of the first byte to decode
     *
     * @param  length
     *         The number of bytes to decode

     * @param  charsetName
     *         The name of a supported {@linkplain java.nio.charset.Charset
     *         charset}
     *
     * @throws  UnsupportedEncodingException
     *          If the named charset is not supported
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code length} arguments index
     *          characters outside the bounds of the {@code bytes} array
     *
     * @since  JDK1.1
     */
    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);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照指定的字符集编码 
     * 解码为一个字符串对象
     * Constructs a new {@code String} by decoding the specified subarray of
     * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
     * The length of the new {@code String} is a function of the charset, and
     * hence may not be equal to the length of the subarray.
     *
     * <p> This method always replaces malformed-input and unmappable-character
     * sequences with this charset's default replacement string.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  offset
     *         The index of the first byte to decode
     *
     * @param  length
     *         The number of bytes to decode
     *
     * @param  charset
     *         The {@linkplain java.nio.charset.Charset charset} to be used to
     *         decode the {@code bytes}
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code length} arguments index
     *          characters outside the bounds of the {@code bytes} array
     *
     * @since  1.6
     */
    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);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照指定的字符集编码 
     * 解码为一个字符串对象(重载) 
     * Constructs a new {@code String} by decoding the specified array of bytes
     * using the specified {@linkplain java.nio.charset.Charset charset}.  The
     * length of the new {@code String} is a function of the charset, and hence
     * may not be equal to the length of the byte array.
     *
     * <p> The behavior of this constructor when the given bytes are not valid
     * in the given charset is unspecified.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  charsetName
     *         The name of a supported {@linkplain java.nio.charset.Charset
     *         charset}
     *
     * @throws  UnsupportedEncodingException
     *          If the named charset is not supported
     *
     * @since  JDK1.1
     */
    public String(byte bytes[], String charsetName)
            throws UnsupportedEncodingException {
        this(bytes, 0, bytes.length, charsetName);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照指定的字符集编码 
     * 解码为一个字符串对象(重载) 
     * Constructs a new {@code String} by decoding the specified array of
     * bytes using the specified {@linkplain java.nio.charset.Charset charset}.
     * The length of the new {@code String} is a function of the charset, and
     * hence may not be equal to the length of the byte array.
     *
     * <p> This method always replaces malformed-input and unmappable-character
     * sequences with this charset's default replacement string.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  charset
     *         The {@linkplain java.nio.charset.Charset charset} to be used to
     *         decode the {@code bytes}
     *
     * @since  1.6
     */
    public String(byte bytes[], Charset charset) {
        this(bytes, 0, bytes.length, charset);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照系统平台 
     * 的默认字符集编码解码为一个字符串对象(重载) 
     * Constructs a new {@code String} by decoding the specified subarray of
     * bytes using the platform's default charset.  The length of the new
     * {@code String} is a function of the charset, and hence may not be equal
     * to the length of the subarray.
     *
     * <p> The behavior of this constructor when the given bytes are not valid
     * in the default charset is unspecified.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @param  offset
     *         The index of the first byte to decode
     *
     * @param  length
     *         The number of bytes to decode
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and the {@code length} arguments index
     *          characters outside the bounds of the {@code bytes} array
     *
     * @since  JDK1.1
     */
    public String(byte bytes[], int offset, int length) {
        checkBounds(bytes, offset, length);
        this.value = StringCoding.decode(bytes, offset, length);
    }

    /**
     * 通过StringCoding类的decode方法将指定的字节数组按照系统平台 
     * 的默认字符集编码解码为一个字符串对象(重载) 
     * 这里没有指定offset,count参数,则默认会直接截取[0,length() -1]范围内的字节即 
     * 默认会直接将整个字节数组解码为一个新的字符串对象 
     * Constructs a new {@code String} by decoding the specified array of bytes
     * using the platform's default charset.  The length of the new {@code
     * String} is a function of the charset, and hence may not be equal to the
     * length of the byte array.
     *
     * <p> The behavior of this constructor when the given bytes are not valid
     * in the default charset is unspecified.  The {@link
     * java.nio.charset.CharsetDecoder} class should be used when more control
     * over the decoding process is required.
     *
     * @param  bytes
     *         The bytes to be decoded into characters
     *
     * @since  JDK1.1
     */
    public String(byte bytes[]) {
        this(bytes, 0, bytes.length);
    }

    /**
     * 根据传入的StringBuffer对象构造一个新的String对象,内部会将StringBuffer对象 
     * 内的字符数组都复制到当前对象的value属性上,注意此方法是加锁的即线程安全的。 
     * Allocates a new string that contains the sequence of characters
     * currently contained in the string buffer argument. The contents of the
     * string buffer are copied; subsequent modification of the string buffer
     * does not affect the newly created string.
     *
     * @param  buffer
     *         A {@code StringBuffer}
     */
    public String(StringBuffer buffer) {
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }

    /**
     * 根据传入的StringBuilder对象构造一个新的String对象,内部会将StringBuilder对象 
     * 内的字符数组都复制到当前对象的value属性上,注意此方法不是线程安全的。 
     * Allocates a new string that contains the sequence of characters
     * currently contained in the string builder argument. The contents of the
     * string builder are copied; subsequent modification of the string builder
     * does not affect the newly created string.
     *
     * <p> This constructor is provided to ease migration to {@code
     * StringBuilder}. Obtaining a string from a string builder via the {@code
     * toString} method is likely to run faster and is generally preferred.
     *
     * @param   builder
     *          A {@code StringBuilder}
     *
     * @since  1.5
     */
    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[].
    */
    String(char[] value, boolean share) {
        // assert share : "unshared not supported";
        this.value = value;
    }

    /**
     * 返回一个字符串的长度,此长度必须等于Unicode编码单元的长度。 
     * 一个Unicode编码单元为16个bit,而一个char字符占2个字节刚好16个bit,即 
     * 一个字符串的长度等于它包含的字符个数。 
     * Returns the length of this string.
     * The length is equal to the number of <a href="Character.html#unicode">Unicode
     * code units</a> in the string.
     *
     * @return  the length of the sequence of characters represented by this
     *          object.
     */
    public int length() {
        return value.length;
    }

    /**
     * 判断一个字符串是否为一个空字符串[""] 
     * 当且仅当字符串的length()等于零,此方法才返回true,否则返回false
     * Returns {@code true} if, and only if, {@link #length()} is {@code 0}.
     *
     * @return {@code true} if {@link #length()} is {@code 0}, otherwise
     * {@code false}
     *
     * @since 1.6
     */
    public boolean isEmpty() {
        return value.length == 0;
    }

    /**
     * 返回字符串某个索引位置的字符 
     * Returns the {@code char} value at the
     * specified index. An index ranges from {@code 0} to
     * {@code length() - 1}. The first {@code char} value of the sequence
     * is at index {@code 0}, the next at index {@code 1},
     * and so on, as for array indexing.
     *
     * <p>If the {@code char} value specified by the index is a
     * <a href="Character.html#unicode">surrogate</a>, the surrogate
     * value is returned.
     *
     * @param      index   the index of the {@code char} value.
     * @return     the {@code char} value at the specified index of this string.
     *             The first {@code char} value is at index {@code 0}.
     * @exception  IndexOutOfBoundsException  if the {@code index}
     *             argument is negative or not less than the length of this
     *             string.
     */
    public char charAt(int index) {
        if ((index < 0) || (index >= value.length)) {
            throw new StringIndexOutOfBoundsException(index);
        }
        return value[index];
    }

  
    
    
    /**
     * index索引位置的字符往后偏移codePointOffset个索引位置,返回偏移后的索引位置 
     * Returns the index within this {@code String} that is
     * offset from the given {@code index} by
     * {@code codePointOffset} code points. Unpaired surrogates
     * within the text range given by {@code index} and
     * {@code codePointOffset} count as one code point each.
     *
     * @param index the index to be offset
     * @param codePointOffset the offset in code points
     * @return the index within this {@code String}
     * @exception IndexOutOfBoundsException if {@code index}
     *   is negative or larger then the length of this
     *   {@code String}, or if {@code codePointOffset} is positive
     *   and the substring starting with {@code index} has fewer
     *   than {@code codePointOffset} code points,
     *   or if {@code codePointOffset} is negative and the substring
     *   before {@code index} has fewer than the absolute value
     *   of {@code codePointOffset} code points.
     * @since 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值