String

作者: 断缨 | 来源:发表于2019-10-23 11:32 被阅读0次

1.定义

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence
  • final类,不可被继承
  • 实现java.io.Serializable接口,可被序列化
  • 实现Comparable<String>,可以进行比较
  • 实现CharSequence,只读有序序列

2.变量

    /**
     * 即 value[] 是用来存储字符的,存储之后不能被修改
     * 使用 @Stable 来表示信任 value[] 中内容,因为value[] 不会为null
     */
    @Stable
    private final byte[] value;

    /**
     * 用来对 value[] 中的byte 进行编码,支持的编码有
     * LATIN1 (ISO-8859-1) 和 UTF16
     */
    private final byte coder;

    /** 缓存字符串的哈希 */
    private int hash; // Default to 0

    /** 序列化Id 标识 */
    private static final long serialVersionUID = -6849794470754667710L;

    /**
     * 如果禁用字符压缩,则value[]中默认是使用UTF-16进行编码
     * 在对于优化JIT编译器时,实例化的值通常是不透明的。
     * 因此在行为敏感的地方,首先检查 静态变量 COMPACT_STRINGS,然后在检查 coder
     * COMPACT_STRINGS 字段的实际值由JVM注入
     */
    static final boolean COMPACT_STRINGS;

    static {
        COMPACT_STRINGS = true;
    }

    /**
     * 类字符串在序列化流协议中是特殊情况
     */
    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

3.构造方法

    /**
     * 1.无参构造,将 “” 赋值给 value
     */
    public String() {
        this.value = "".value;
        this.coder = "".coder;
    }

     /**
     * 2.有参构造,将 original 的值赋给 新的 String
     */
    @HotSpotIntrinsicCandidate
    public String(String original) {
        this.value = original.value;
        this.coder = original.coder;
        this.hash = original.hash;
    }

    /**
     * 3.有参构造,将 value[] 的值赋给 新的 String
     */
    public String(char value[]) {
        this(value, 0, value.length, null);  // this 调用方法如下
    }

     /**
     * 4.有参构造,作上面3的补充,将 value[] 的值赋给 新的 String,例子如下:
     *  char[] test = {'1','2','3','4','5','6','7','8','9','0'};
     *  String b = new String(test,2,3); // "345"
     */
    public String(char value[], int offset, int count) {
        this(value, offset, count, rangeCheck(value, offset, count));
    }

    /**
     * 检查是否存在越界操作
     */
    private static Void rangeCheck(char[] value, int offset, int count) {
        checkBoundsOffCount(offset, count, value.length);
        return null;
    }
    
     /**
     * 将 char value[] 的转存为 bytes[]
     */
    String(char[] value, int off, int len, Void sig) {
        if (len == 0) {
            this.value = "".value;
            this.coder = "".coder;
            return;
        }
        if (COMPACT_STRINGS) {
            byte[] val = StringUTF16.compress(value, off, len);
            if (val != null) {
                this.value = val;
                this.coder = LATIN1;
                return;
            }
        }
        this.coder = UTF16;
        this.value = StringUTF16.toBytes(value, off, len);
    }

/**
     *   bytes[] 构造 ,charsetName 为字符集
     * @throws  UnsupportedEncodingException  如果不支持该字符集,则抛出异常
     * @throws  IndexOutOfBoundsException 如果offset或者 length存在问题则抛异常
     */
    public String(byte bytes[], int offset, int length, String charsetName)
            throws UnsupportedEncodingException {
        if (charsetName == null)
            throw new NullPointerException("charsetName");
        checkBoundsOffCount(offset, length, bytes.length);
        StringCoding.Result ret =
            StringCoding.decode(charsetName, bytes, offset, length);
        this.value = ret.value;
        this.coder = ret.coder;
    }

  
    /**
     * bytes[] 其他构造
     */
    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) {
        checkBoundsOffCount(offset, length, bytes.length);
        StringCoding.Result ret = StringCoding.decode(bytes, offset, length);
        this.value = ret.value;
        this.coder = ret.coder;
    }

    public String(byte[] bytes) {
        this(bytes, 0, bytes.length);
    }

    // StringBuffer构造
    public String(StringBuffer buffer) {
        this(buffer.toString());
    }
    
    // StringBuilder构造
    public String(StringBuilder builder) {
        this(builder, null);
    }

4.常用方法

  • 长度
    public int length() {
        return value.length >> coder();
    }

    byte coder() {
        // 其中 UTF16 = 1   coder = 0
        return COMPACT_STRINGS ? coder : UTF16;  
    }
  • 判空
    public boolean isEmpty() {
        return value.length == 0;
    }

  • charAt
    // 返回字符串中的第index位置的值
    public char charAt(int index) {
        if (isLatin1()) {
            return StringLatin1.charAt(value, index);
        } else {
            return StringUTF16.charAt(value, index);
        }
    }

5.不常用方法

  • codePointAt
   // 返回字符串中的index 位置处的Unicode码
   public int codePointAt(int index) {
        if (isLatin1()) {
            checkIndex(index, value.length);
            return value[index] & 0xff;
        }
        int length = value.length >> 1;
        checkIndex(index, length);
        return StringUTF16.codePointAt(value, index, length);
    }

StringUTF16.codePointAt()

    public static int codePointAt(byte[] value, int index, int end) {
       return codePointAt(value, index, end, false /* unchecked */);
    }

    private static int codePointAt(byte[] value, int index, int end, boolean checked) {
        assert index < end;
        if (checked) {
            checkIndex(index, value);
        }
        char c1 = getChar(value, index);
        if (Character.isHighSurrogate(c1) && ++index < end) {
            if (checked) {
                checkIndex(index, value);
            }
            char c2 = getChar(value, index);
            if (Character.isLowSurrogate(c2)) {
               return Character.toCodePoint(c1, c2);
            }
        }
        return c1;
    }

相关文章

网友评论

      本文标题:String

      本文链接:https://www.haomeiwen.com/subject/ygmhvctx.html