Java9 后String 为什么使用byte[]而不是char?

之前认知里面,java的String一直是使用char数组,但是今天点进去瞟了一眼,发现不对。
源码如下:

    /**
     * The value is used for character storage.
     *
     * @implNote This field is trusted by the VM, and is a subject to
     * constant folding if String instance is constant. Overwriting this
     * field after construction will cause problems.
     *
     * Additionally, it is marked with {@link Stable} to trust the contents
     * of the array. No other facility in JDK provides this functionality (yet).
     * {@link Stable} is safe here, because value is never null.
     */
    @Stable
    private final byte[] value;

这分明就是byte数组,哪里是char了?于是上网查了下,这个改动在 Java9以后就发生了。

为什么有这个改动?char -> byte
主要还是节省空间。

JDK9 之前的库的 String 类的实现使用了 char 数组来存放字符串,char 占用16位,即两字节。

private final char value[];

这种情况下,如果我们要存储字符A,则为0x00 0x41,此时前面的一个字节空间浪费了。但如果保存中文字符则不存在浪费的情况,也就是说如果保存 ISO-8859-1编码内的字符则浪费,之外的字符则不会浪费。

而 JDK9 后 String 类的实现使用了 byte 数组存放字符串,每个 byte 占用8位,即1字节。
private final byte[] value
但是如果遇到ISO-8859-1 编码外的字符串呢?比如中文咋办?

Java9之后String的新属性,coder编码格式
借用网上盗的一个图:


Java String的演进

    private final byte coder;
    static final boolean COMPACT_STRINGS;
    static {
        COMPACT_STRINGS = true;
    }
    byte coder() {
        return COMPACT_STRINGS ? coder : UTF16;
    }
    @Native static final byte LATIN1 = 0;
    @Native static final byte UTF16  = 1;

是编码格式的标识,在计算字符串长度或者调用 indexOf() 函数时,需要根据这个字段,判断如何计算字符串长度。
coder 属性默认有 0 和 1 两个值。如果 String判断字符串只包含了 Latin-1,则 coder 属性值为 0 ,反之则为 1

  • 0 代表Latin-1(单字节编码)
  • 1 代表 UTF-16 编码。。
    Java9 默认打开COMPACT_STRINGS, 而如果想要取消紧凑的布局可以通过配置 VM 参数-XX:-CompactStrings实现。
  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ok060

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值