要看String类的长度限制,肯定要先从String的源码实现看起,这里就以目前使用最多的JDK8为例来进行说明。JDK9及以后String的底层实现有所变化,大家可参考《JDK9对String字符串的新一轮优化》一文。

我们都知道,String类提供了一个length方法,我们是否可以直接通过这个方法得知String的最大长度?

/**
 * Returns the length of this string.
 * The length is equal to the number of <a href="Character.html#unicode">Unicode
 * code units</a> in the string.
 *
 * @return  the length of the sequence of characters represented by this
 *          object.
 */
public int length() {
    return value.length;
}

这里文档并没有说明最大长度是多少,但我们可以从返回的结果类型得知一些线索。结果类型为int,也就是说int的取值范围便是限制之一。

 

如果你知道int在正整数部分的取值范围为2^31 -1那很好,如果不知道,可以查看对应的包装类Integer:

public final class Integer extends Number implements Comparable<Integer> {
    /**
     * A constant holding the minimum value an {@code int} can
     * have, -2<sup>31</sup>.
     */
    @Native public static final int   MIN_VALUE = 0x80000000;

    /**
     * A constant holding the maximum value an {@code int} can
     * have, 2<sup>31</sup>-1.
     */
    @Native public static final int   MAX_VALUE = 0x7fffffff;
    // ...
}

无论MIN_VALUE和MAX_VALUE的值或注释都说明了int的取值范围。此时计算一下String的最大长度应该是:

2^31 - 1 = 2147483647

回到length方法,我们看到length的值是通过是value获得的,而value在JDK8中是以char数组实现的:

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
    // ...   
}

 

Java中内码(运行内存)中的char使用UTF16的方式编码,一个char占用两个字节。所以,还需要从将上面计算的值乘以2。

此时的计算公式为:

2^31-1 =2147483647 个16-bit Unicodecharacter

2147483647 * 2 = 4294967294 (Byte)
 
4294967294 / 1024 = 4194303.998046875 (KB)
 
4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)
 
4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)

 

java面试题:

java实习生(大厂面试题)| 智一面