私は良いの文字列を持っていると述べ、インタビュアーが実際にJavaのStringに私に尋ねたいかなる長さの制限がありません!?

JavaのStringは文字列で、実際には、まだ簡単に見落とさ多くのものがあり、基本的なデータ型に加えて、文字列は、最も広く使用され、データの非常に重要なタイプですが、。

この論文として、我々は問題を議論:String内のJavaには長さの制限がありませんか?

質問は、すなわち、コンパイルして実行、二つの段階を表示します。異なるタイムリミットは同じではありません。

コンパイル

まず、我々は、コードのString =「を使用する場合について合理的な推論みましょう」を、Stringオブジェクトは、時間の形式を定義するには、「」そこの文字数制限をそこに?

それは合理的な推論があるので、公共の文字列(char値[]、オフセットINT、INTカウント)が定義され、カウント値がint型、従って、チャーによれば、十分な根拠でなければならないので、我々は、文字列のソースから開始することができます値は[]あなたはInteger.MAX_VALUEで、つまり2147483647文字まで保存することができます。(Jdk1.8.0_73)

しかし、実験は、文字列S =は「」;、あなたには、最大65,534文字を持つことができます。あなたは、この数を超えた場合。これは、コンパイル時にエラーになります。

public static void main(String[] args) {

    String s = "a...a";// 共65534个a
    System.out.println(s.length());

    String s1 = "a...a";// 共65535个a
    System.out.println(s1.length());
}
复制代码

上記のコードは、文字列S1 =になります「...」; //コンパイルで65535の合計が失敗しました:

✗ javac StringLenghDemo.java
StringLenghDemo.java:11: 错误: 常量字符串过长
复制代码

65535の文字はそれをコンパイルすることはできません理由は、良い長さの制限が2147483647であることは明らかですか?

私たちは、文字列リテラルは、直接文字列を定義し使用する場合、文字列は、ストレージの定数プールになります。65534次に、上記事実は、定数プールを制限することです。

定数プール内の各データ項目は、独自の型を持ちます。定数プールで表されるJavaのCONSTANT_Utf8型のUnicode文字列のUTF-8エンコーディング。

CONSTANTUtf8info CONSTANTUtf8タイプは、それが格納されている文字列定数であり、定数プール・データ項目です。すべてのリテラル定数プールは、ほとんどの場合CONSTANTUtf8infoによって記述されています。次のようにCONSTANTUtf8_infoが定義されて:

CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}
复制代码

この記事の焦点はCONSTANTUtf8info紹介ではないので、ここでは詳細に起動しない、と私たちはCONSTANTUtf8infoを使用して保存されているクラスファイルで定義されたリテラル私たちの文字列を使用する必要がある、とCONSTANTUtf8infoはU2の長さを持つ、タイプを示します格納されたデータの長さ。

U2は、符号なし16ビット整数、最大許容長は、理論的に2 ^ 16 = 65536です。Javaクラスファイルは、このように65536から2 = 65534バイトを残して、表現するために2つのバイトを使用して、null値を持つ文字バリアントを保存するためのUTF-8形式です。

この点で、クラスファイル形式の仕様にも明記されています。

The length of field and method names, field and method descriptors, and other constant string values is limited to 65535 characters by the 16-bit unsigned length item of the CONSTANTUtf8info structure (§4.4.7). Note that the limit is on the number of bytes in the encoding and not on the number of encoded characters. UTF-8 encodes some characters using two or three bytes. Thus, strings incorporating multibyte characters are further constrained.
复制代码

これは、Javaで、すべてのデータが定数プール内に保存する必要がある、もちろん、少し文字列の定義に含まれていない以上65,535の最大長、。

ランタイム

リテラル方法とき、この定義はいくつかの限界になり、文字列これは、文字列S =「は」使用されているコンパイラの上記制限の長さを制限します。

まあ。実行時に文字列は制限はありません、答えは、我々は前に述べたことがInteger.MAX_VALUEのことであり、この値は、文字列の長さがこの範囲を超えた場合、それは例外をスローすることが、実行時に、4Gにほぼ等しいです。(JDK 1.9前)

int型は、32ビットの変数である単語をカウントする正の数の一部を取り、彼らはまで可能

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

2147483647 * 16 = 34359738352 位
34359738352 / 8 = 4294967294 (Byte)
4294967294 / 1024 = 4194303.998046875 (KB)
4194303.998046875 / 1024 = 4095.9999980926513671875 (MB)
4095.9999980926513671875 / 1024 = 3.99999999813735485076904296875 (GB)
复制代码

これは、ほぼ4Gの容量を有します。

おすすめ

転載: juejin.im/post/5d53653f5188257315539f9a