java基础类String源码分析

目录

简介

字段

创建string

构造器

参数为string,char

参数为代码点

参数为byte

参数为stringbuilder和stringbuffer

ValueOf

intern

String的创建后的等于

CharSequence的方法

length和isEmpty

charAt

subSequence和subString

比较方法

compareTo

无视大小写的比较

基本方法

toString

equals

hashcode

得到代码点,代码点数量,代码点偏移量

得到bytes数组


简介

string是java中的字符串类

/**
 * 
 * <p>String类代表字符串。java程序中的所有字符串常量,例如"abc",是这个类的实例。
 * 
 * <p>字符串是常量,它们的值不能在被创造后改变。字符串缓冲区支持可变的字符串。
 * 字符串对象是不可变的,因为它们能被共享。例如:
 * 
 * <blockquote><pre>
 *     String str = "abc";
 * </pre></blockquote><p>
 *  等价于
 * <blockquote><pre>
 *     char data[] = {'a', 'b', 'c'};
 *     String str = new String(data);
 * </pre></blockquote><p>
 * 下面有更多的字符串如何被使用的例子:
 * <blockquote><pre>
 *     System.out.println("abc");
 *     String cde = "cde";
 *     System.out.println("abc" + cde);
 *     String c = "abc".substring(2,3);
 *     String d = cde.substring(1, 2);
 * </pre></blockquote>
 * 
 * <p>String类包含了各种方法,包括检查序列中单独的字符,比较字符串,
 * 查询字符串,抽取子序列,创造一个所有字符变为大小或小写的字符串副本。
 * 大小写映射基于Character类指定的Unicode的标准版本。
 * 
 * <p>java语言为字符串连接符号(+)和其他对象转为字符串提供了特殊的支持。
 * 字符串连接由StringBuilder或者StringBuffer类和它们的方法来实现。
 * 字符串转换由方法toString来实现,这个方法被Ojbect定义,并且被java中所有的类继承,可以看java语言规范。
 * 
 * <p>除非另有说明,传入这个类的构造器或方法一个null参数会导致抛出NullPointerException
 * 
 * <p>字符串代表UTF-16格式的字符串,其中补充字符有代理对标识(看Character类的Unicode Character Representation)。
 * 索引值对应char的代码单元,所以一个补充字符在String中占用两个位置(两个代码单元)。
 * 而正常字符和补充字符都对应一个代码点,但可能有1-2个代码单元。
 * 就是说每个字符可能对应1-2个char,有的字符可能在char数组中占据两个位置。
 * 
 * <p>String类提供了处理Unicode代码点和处理Unicode代码单元的方法。
 *
 * @author  Lee Boynton
 * @author  Arthur van Hoff
 * @author  Martin Buchholz
 * @author  Ulf Zibis
 * @see     java.lang.Object#toString()
 * @see     java.lang.StringBuffer
 * @see     java.lang.StringBuilder
 * @see     java.nio.charset.Charset
 * @since   JDK1.0
 */

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

字段

    /** 用来保存字符的值 ,注意:这是一个char序列,而且是final的,不可更改*/
    private final char value[];

    /** 缓存字符串的hash码*/
    private int hash; // 默认为0

    /** use serialVersionUID from JDK 1.0.2 for interoperability */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * 类字符串在序列化流协议中使用特殊的大小写。
     * 一个字符串实例根据类的序列化规范来写入ObjectOutputStream。
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

创建string

构造器

参数为string,char

    /**
     * 初始化一个新建的String对象,从而它代表一个空的字符串序列。
     * 注意这个构造器是不需要的,因为字符串是不可变的。
     */
    public String() {
        this.value = "".value;
    }

    /**
     * 初始化一个新建的String对象,从而它代表与参数相同的字符串序列。
     * 换言而之,新建的字符串是参数字符串的拷贝。
     * 除非需要一个original的独一无二的拷贝,不需要使用这个构造器,因为字符串是不可更改的
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    /**
     * 分配一个新字符串,从而它代表的字符串序列包含了字符序列参数。
     * 字符序列的内容被拷贝了。
     * 之后对参数字符序列的修改不影响新建的字符串。
     *
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
    	//value值为一个复制的新数组。
        this.value = Arrays.copyOf(value, value.length);
    }

    /**
     * 分配一个新的String,它包含了参数字符数组的一个子数组。
     * offset参数是子数组的第一个字符的位置,count参数指定了子数组的长度。
     * 子数组的内容被复制。之后对字符数组的修改不影响新建的字符串。
     *
     * @param  value
     *         Array that is the source of characters
     *
     * @param  offset
     *         The initial offset
     *
     * @param  count
     *         The length
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code count} arguments index
     *          characters outside the bounds of the {@code value} array
     */
    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) {
            	//如果count==0而且offset<=value.length
            	//建一个空字符串
                this.value = "".value;
                return;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > value.length - count) {
        	//如果offset+count>value.length,报错
            throw new StringIndexOutOfBoundsException(offset + count);
        }
        //将value数组的一部分复制到一个新的char数组
        this.value = Arrays.copyOfRange(value, offset, offset+count);
    }

参数为代码点

    /**
     * 分配一个新的String,包含从一个Unicode代码点数组参数的子数组的字符。
     * offset参数是子数组的第一个代码点的位置,count参数指定了子数组的长度。
     * 子数组的内容被转换为char,之后对int数组的修改不影响新建的string
     *
     * @param  codePoints  Unicode代码点来源数组
     *
     * @param  offset
     *         The initial offset
     *
     * @param  count
     *         The length
     *
     * @throws  IllegalArgumentException
     *          If any invalid Unicode code point is found in {@code
     *          codePoints}  
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} and {@code count} arguments index
     *          characters outside the bounds of the {@code codePoints} array
     *
     * @since  1.5
     */
    public String(int[] codePoints, int offset, int count) {
        if (offset < 0) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= codePoints.length) {
            	//如果count<=0而且offset处于正常返回,返回空字符串
                this.value = "".value;
                return;
            }
        }
        // 注意: offset 或 count 可能接近Integer.max
        if (offset > codePoints.length - count) {
        	//如果offset+count>length
            throw new StringIndexOutOfBoundsException(offset + count);
        }

        final int end = offset + count;

        // Pass 1: 计算char数组的准确大小
        int n = count; //初始大小为count
        for (int i = offset; i < end; i++) {
            int c = codePoints[i];
            if (Character.isBmpCodePoint(c))
            	//如果代码点是BMP代码点,就为一个代码单元,大小不变
                continue;
            else if (Character.isValidCodePoint(c))
            	//如果不是BMP,但是是合法的代码点,就为两个代码单元,大小+1
                n++;
            //都不是的话,说明代码点是非法的
            else throw new IllegalArgumentException(Integer.toString(c));
        }

        // Pass 2: 分配并填充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))
            	//如果c是BMP代码点,直接填充
                v[j] = (char)c;
            else
            	//否则j为c的高代理代码单元,j++为低代理代码单元
                Character.toSurrogates(c, v, j++);
        }
        
        //最后value为填充完的char数组
        this.value = v;
    }

参数为byte

   /**
     * Allocates a new {@code String} constructed from a subarray of an array
     * of 8-bit integer values.
     *
     * <p> The {@code offset} argument is the index of the first byte of the
     * subarray, and the {@code count} argument specifies the length of the
     * subarray.
     *
     * <p> Each {@code byte} in the subarray is converted to a {@code char} as
     * specified in the method above.
     *
     * @deprecated This method does not properly convert bytes into characters.
     * As of JDK&nbsp;1.1, the preferred way to do this is via the
     * {@code String} constructors that take a {@link
     * java.nio.charset.Charset}, charset name, or that use the platform's
     * default charset.
     *
     * @param  ascii
     *         The bytes to be converted to characters
     *
     * @param  hibyte
     *         The top 8 bits of each 16-bit Unicode code unit
     *
     * @param  offset
     *         The initial offset
     * @param  count
     *         The length
     *
     * @throws  IndexOutOfBoundsException
     *          If the {@code offset} or {@code count} argument is invalid
     *
     * @see  #String(byte[], int)
     * @see  #String(byte[], int, int, java.lang.String)
     * @see  #String(byte[], int, int, java.nio.charset.Charset)
     * @see  #String(byte[], int, int)
     * @see  #String(byte[], java.lang.String)
     * @see  #String(byte[], java.nio.charset.Charset)
     * @see  #String(byte[])
     */
    @Deprecated
    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;
    }

    /**
     * Allocates a new {@code String} containing characters constructed from
     * an array of 8-bit integer values. Each character &
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值