Java基础对象:String类

类继承关系,成员和构造函数(非过期部分)

//实现了比较器和charSequence。CharSequence提供了一系列可读char序列的方法。JDK9之后添加Constable, ConstantDesc两个新的接口实现
public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
   /**
    关于String 类内部存储:
jdk9时 开发人员调研了成千上万个应用程序的 heap dump 信息,他们注意到大多数字符串都是以 Latin-1 字符编码表示的,它只需要一个字节存储就够了,两个字节完全是浪费,这比 char 数据类型存储少 50%(1 个字节)。
Java 9 这样调整的目的是减小字符串的内存占用,这样带来了两个好处:
节省内存:对于包含大量ASCII字符的字符串,内存占用大幅减少,因为每个字符只占用一个字节而不是两个字节。
提高性能:由于字符串的存储结构与编码方式更加紧凑,字符串操作的性能也有所提高。
在 Java 9 中,String 支持的字符编码格式有两种:
Latin-1:Latin-1 编码用于存储只包含拉丁字符的字符串。它采用了一字节编码,每个字符占用一个字节(8位)。
UTF-16:UTF-16 编码用于存储包含非拉丁字符的字符串,以及当字符串包含不适合 Latin-1 编码的字符时。

-XX:-CompactStrings会强制禁止所有字符串精简,即全部使用UTF-16处理
  **/
//jdk8实现
    private final char value[];
//jdk9+实现
    @Stable
    private final byte[] value;
   //判断编码格式的成员
    private final byte coder;

    /** Cache the hash code for the string */
    private int hash; // Default to 0

    private static final long serialVersionUID = -6849794470754667710L;

    private static final ObjectStreamField[] serialPersistentFields =
        new ObjectStreamField[0];

//最简单的初始化,可以看到value被赋予了一个空值
    public String() {
        this.value = "".value;
    }

//比较常见的初始化方式之一,可以看到由于只是赋予(copy)了value和hash值,实际上指向的是两个对象
    public String(String original) {
        this.value = original.value;
        this.hash = original.hash;
    }

    public String(char value[]) {
        this.value = Arrays.copyOf(value, value.length);
    }

//指定子序列的相关操作
    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);
    }

    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;
            }
        }
        // Note: offset or count might be near -1>>>1.
        if (offset > codePoints.length - count) {
            throw new StringIndexOutOfBoundsException(offset + count);
        }

        final int end = offset + count;

        // Pass 1: Compute precise size of 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));
        }

        // Pass 2: Allocate and fill in 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;
    }

    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);
    }

    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);
    }

//使用stringbuffer等字符串工具类创建
    public String(StringBuffer buffer) {
//为避免修改锁定了buffer对象
        synchronized(buffer) {
            this.value = Arrays.copyOf(buffer.getValue(), buffer.length());
        }
    }

    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;
    }
}
posted @   hwh405  阅读(4)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
点击右上角即可分享
微信分享提示