String类表示一个字符串(character strings)。Java programs中的所有的string字母,像”abc”,都是作为该类的实例来实现的;

Strings是一个恒定的,不变的;在被创建后,他们的值不允许被改变;String buffers支持值可变的strings;

因为String对象是不可变的,所以他们可以被共享;例如

String str="abc";

就等价于

char data[] = {'a','b','c'};
String str = new String(data);

这里有一些更多的例子关于strings是如何使用的:

System.out.println("abc");
     String cde = "cde";
     System.out.println("abc" + cde);
     String c = "abc".substring(2,3);
     String d = cde.substring(1, 2);

String类包含独立的顺序的字母方法检查,比较strings,查询strings,substring,创建一个复制string的大写,或者小写;因为映射是基于Unicode标准版本的,尤其是java.lang.Character类;

Java语言提供特殊的string串联操作支持,并且提供转换其他类为strings;String串联实现了StringBuilder和StringBuffer类和其方法;
String类转换实现了toString方法,通过Object定义并且被Java中的所有类继承;此外,string串联和转换的信息可以在Gosling,Joy和Steele中查看;

一个String类代表了一个UTF-16格式的字符串,这个字符串补充了被替代的字符对;

下标的值表示char的单元编码,因此,一个追加的字符在String中使用两个位置;

String类提供一个处理Unicode编码点的方法,例如character,此外还适用于对于处理Unicode编码单元,例如char;

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** 该值用于字符串存储. */
    private final char value[];

    /** string的hash编码缓存 */
    private int hash; // 默认是0

    /** 从JDK1.0.2版本开始,使用序列版本UID来增强互用性*/
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     *String类在序列化流协议中是特殊的
     * 一个String实例被写入进一个ObjectOutputStream 根据
     * <a href="{@docRoot}/../platform/serialization/spec/output.html">
     * 对象序列化规范, 6.2部分, 名为:"Stream Elements"</a>
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

    /**
     * 初始化一个新建的String对象,因此它代表一个空的字符序列注意使用构造器是非必须的
     * 因为String是一成不变的;
     */
    public String() {
        this.value = "".value;
    }

    /**
     * 初始化一个新创建的String对象,因此它代表与参数相同的字符序列
     * 换句话说,新创建的string是参数string. 除非明确了是original副本
     * 使用构造器是非必须的,因为Strings类是不可变化的;
     *
     * @param  original
     *         A {@code String}
     */
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    /**
     * 分配一个新建的String类,因此他代表包含字符数据参数的暂时的字符的序列
     * 字符数组的内容是被赋值过的,随后的修改的字符串数组不会影响刚刚新建的string
     * @param  value
     *         The initial value of the string
     */
    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

    /**
     * 分配一个新建的包含从字符串数据参数的子数组的字符String类
     * offset参数是子数组的第一个字符的下标 count参数指定了子数组的长度
     * 子数组副本的内容是被复制过的
     * 随后字符数组的修改不会影响新建的string;
     * @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) {
            throw new StringIndexOutOfBoundsException(offset);
        }
        if (count <= 0) {
            if (count < 0) {
                throw new StringIndexOutOfBoundsException(count);
            }
            if (offset <= value.length) {
                this.value = "".value;
                return;
            }
        }
        // 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);
    }

    /**
     * 分配一个新建的包含Unicode编码的子数组字符的参数的String类
     * offset参数是子数组的第一个编码点的下标;count参数指定了子数组的长度
     * 子数组的内容被转换成char字符
     *  随后int数组的修改不会影响新创建的string
     * @param  codePoints
     *         Array that is the source of Unicode code points
     *
     * @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) {
                this.value = "".value;
                return;
            }
        }
        // 注意: offset或 count 可能接近-1>>>1.
        if (offset > codePoints.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }

        final int end = offset + count;

        // 过程1: 精确计算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));
        }

        // 过程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))
                v[j] = (char)c;
            else
                Character.toSurrogates(c, v, j++);
        }

        this.value = v;
    }

    /**
     * 分配一个新建的String,从一个8位的integer类型的值的子数组构造而来;
     * offset参数是子数组的第一个字节的下标;count参数指定了子数组的长度;
     * 每一个子数组的字节被转换成char因为被上面的方法指定了;
     * @deprecated:这个方法不是正式的转换字节为字符,所以弃用; 
     * 因为JDK1.1, 最优先的是通过String的字符串集合类,字符集合名或者使用平台默认的
     * 字符集合的构造器来创建;
     * @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;
    }
    ...(未完待续)
}

检查是否越界方法:判读由一个byte[]中截取来的String是否可以截取过来:

//测试类
public class StringTest {
    public static void main(String[] args) {

        byte[] byteArray= new byte[]{'a','b','c'};
        checkBounds(byteArray,1,1);

    }
//java.lang.String类中的源码
    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);
    }
}

java string 在哪个包下 strings java_java string 在哪个包下


上图我们从一个数组中,构造一个”boy”的String类型的对象,构造前先检查下是否越界;