133

Trong Java , kích thước tối đa mà một Stringđối tượng có thể có là gì, tham khảo lệnh length()gọi phương thức?

Tôi biết rằng length()trả về kích thước của a Stringlà a char [];

|
  • 4

    Mặc dù Stringvề mặt lý thuyết Integer.MAX_VALUE, độ dài của a là độ dài của một chuỗi ký tự trong nguồn dường như bị giới hạn chỉ với 65535 byte dữ liệu UTF-8.

    – Đỗ Thụy Ðào 05:46:37 13/11/2013
152

Xem xét phương thức Stringcủa lớp lengthtrả về một int, độ dài tối đa mà phương thức sẽ trả về sẽ Integer.MAX_VALUE2^31 - 1(hoặc khoảng 2 tỷ.)

Về độ dài và lập chỉ mục của các mảng, (chẳng hạn như char[], có lẽ là cách triển khai dữ liệu nội bộ cho Strings), Chương 10: Mảng của Đặc tả ngôn ngữ Java, Phiên bản Java SE 7 cho biết như sau:

Các biến chứa trong một mảng không có tên; thay vào đó, chúng được tham chiếu bởi các biểu thức truy cập mảng sử dụng các giá trị chỉ số nguyên không âm. Các biến này được gọi là các thành phần của mảng. Nếu một mảng có ncác thành phần, chúng ta nói nchiều dài của mảng; các thành phần của mảng được tham chiếu bằng các chỉ số nguyên từ 0đến n - 1, bao gồm.

Hơn nữa, việc lập chỉ mục phải theo intcác giá trị, như được đề cập trong Phần 10.4 :

Mảng phải được lập chỉ mục bởi intcác giá trị;

Do đó, dường như giới hạn là thực sự 2^31 - 1, vì đó là giá trị tối đa cho một intgiá trị không âm .

Tuy nhiên, có lẽ sẽ có những hạn chế khác, chẳng hạn như kích thước phân bổ tối đa cho một mảng.

|
  • 1

    Integer.MAX_VALUE là 2 ^ 31-1, thực sự. :)

    – Trịnh Ngân Hà 02:38:49 03/05/2009
  • 1

    Người đàn ông trả lời tuyệt vời! Tôi đã xem mã nguồn String.java và nó đúng, 'Count' là biến int trả về độ dài của mảng char và mảng char được lưu trữ trên biến 'value' (như char []) kích thước Chuỗi có thể khoảng 2GB. Tất nhiên có thể có những hạn chế để phân bổ kích thước bộ nhớ như vậy. Cảm ơn!

    – Dương Tâm Nguyên 03:45:21 03/05/2009
  • 1

    Tôi vừa thử định nghĩa một chuỗi ký tự trong chương trình java thế giới xin chào dài hơn 65546. javacđưa ra một lỗi về nghĩa đen đó quá dài:javac HelloWorld.java 2>&1|head -c 80 HelloWorld.java:3: constant string too long

    – Tạ Ðức Quảng 19:59:49 15/07/2011
  • 1

    @dlamblin: Nghe có vẻ như giới hạn javacđối với String chữ (không phải Stringđối tượng), vì tôi không thể tìm thấy bất kỳ tham chiếu nào về giới hạn kích thước đối với Stringchữ trong Đặc tả ngôn ngữ Java và Đặc tả JVM. Tôi đã thử tạo một Stringký tự lớn hơn 100.000 ký tự và trình biên dịch Eclipse không gặp vấn đề gì khi biên dịch nó. (Và chạy chương trình đã có thể cho thấy rằng chữ có số lượng String.lengthlớn hơn 100.000.)

    – Lý Mỹ Xuân 03:17:59 16/07/2011
  • 1

    @Premraj Đó là ba năm trước vì vậy tôi phải suy nghĩ về nó. ;) Ý tôi là; để xây dựng một chuỗi có kích thước tối đa bạn cần rất nhiều bộ nhớ, có thể nhiều hơn bạn có. Bạn cần hai byte cho mỗi ký tự ~ 4GB, nhưng bạn cần xây dựng mã này từ StringBuilder hoặc char [], nghĩa là bạn cần thêm hai byte cho mỗi ký tự để tạo nó ở vị trí đầu tiên, tức là ~ 4 GB (ít nhất là tạm thời)

    – Vũ Thành Vinh 16:16:57 25/05/2012
20

java.io.DataInput.readUTF()java.io.DataOutput.writeUTF(String)nói rằng một Stringđối tượng được biểu thị bằng hai byte thông tin độ dài và biểu diễn UTF-8 đã sửa đổi của mỗi ký tự trong chuỗi. Điều này kết luận rằng độ dài của Chuỗi bị giới hạn bởi số byte của biểu diễn UTF-8 đã sửa đổi của chuỗi khi được sử dụng với DataInputDataOutput.

Ngoài ra, Đặc tả kỹ thuậtCONSTANT_Utf8_info được tìm thấy trong đặc tả máy ảo Java định nghĩa cấu trúc như sau.

CONSTANT_Utf8_info {
    u1 tag;
    u2 length;
    u1 bytes[length];
}

Bạn có thể thấy rằng kích thước của 'chiều dài' là hai byte .

Rằng kiểu trả về của một phương thức nhất định (ví dụ String.length()) intkhông phải lúc nào cũng có nghĩa là giá trị tối đa được phép của nó là Integer.MAX_VALUE. Thay vào đó, trong hầu hết các trường hợp, intđược chọn chỉ vì lý do hiệu suất. Đặc tả ngôn ngữ Java nói rằng các số nguyên có kích thước nhỏ hơn kích thước intđược chuyển đổi thành inttrước khi tính toán (nếu bộ nhớ của tôi phục vụ cho tôi chính xác) và đó là một lý do để chọn intkhi không có lý do đặc biệt.

Độ dài tối đa tại thời gian biên dịch tối đa là 65536. Xin lưu ý lại rằng độ dài là số byte của biểu diễn UTF-8 đã sửa đổi , không phải số lượng ký tự trong một Stringđối tượng.

Stringcác đối tượng có thể có nhiều ký tự hơn trong thời gian chạy. Tuy nhiên, nếu bạn muốn sử dụng Stringcác đối tượng DataInputDataOutputgiao diện, tốt hơn là tránh sử dụng Stringcác đối tượng quá dài . Tôi đã tìm thấy giới hạn này khi tôi triển khai các tương đương Objective-C DataInput.readUTF()DataOutput.writeUTF(String).

|
18

Do các mảng phải được lập chỉ mục với các số nguyên, nên độ dài tối đa của một mảng là Integer.MAX_INT(2 31 -1 hoặc 2 147 483 647). Tất nhiên, điều này là giả sử bạn có đủ bộ nhớ để giữ một mảng có kích thước đó.

|
5

rõ ràng nó bị ràng buộc với một int, đó là 0x7FFFFFFF (2147483647).

|
4

Tôi có iMac 2010 với 8GB RAM, chạy Eclipse neon.2 Release (4.6.2) với Java 1.8.0_25. Với đối số VM -Xmx6g, tôi đã chạy đoạn mã sau:

StringBuilder sb = new StringBuilder();
for (int i = 0; i < Integer.MAX_VALUE; i++) {
    try {
        sb.append('a');
    } catch (Throwable e) {
        System.out.println(i);
        break;
    }
}
System.out.println(sb.toString().length());

Bản in này:

Requested array size exceeds VM limit
1207959550

Vì vậy, có vẻ như kích thước mảng tối đa là ~ 1.207.959.549. Sau đó, tôi nhận ra rằng chúng ta không thực sự quan tâm nếu Java hết bộ nhớ: chúng ta chỉ tìm kích thước mảng tối đa (dường như là một hằng số được xác định ở đâu đó). Vì thế:

for (int i = 0; i < 1_000; i++) {
    try {
        char[] array = new char[Integer.MAX_VALUE - i];
        Arrays.fill(array, 'a');
        String string = new String(array);
        System.out.println(string.length());
    } catch (Throwable e) {
        System.out.println(e.getMessage());
        System.out.println("Last: " + (Integer.MAX_VALUE - i));
        System.out.println("Last: " + i);
    }
}

Bản in nào:

Requested array size exceeds VM limit
Last: 2147483647
Last: 0
Requested array size exceeds VM limit
Last: 2147483646
Last: 1
Java heap space
Last: 2147483645
Last: 2

Vì vậy, có vẻ như tối đa là Integer.MAX_VALUE - 2 hoặc (2 ^ 31) - 3

PS Tôi không chắc tại sao StringBuildertối đa của tôi lại 1207959550trong khi char[]tối đa của tôi ở (2 ^ 31) -3. Có vẻ như AbstractStringBuildertăng gấp đôi kích thước bên trong của nó char[]để phát triển nó, do đó có thể gây ra vấn đề.

|
3

Kiểu trả về của phương thức length () của lớp String là int .

độ dài int int ()

Tham khảo http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#length ()

Vậy giá trị tối đa của int là 2147483647 .

Chuỗi được coi là mảng char trong nội bộ, vì vậy việc lập chỉ mục được thực hiện trong phạm vi tối đa. Điều này có nghĩa là chúng tôi không thể lập chỉ mục cho thành viên thứ 2147483648. Vì vậy, độ dài tối đa của Chuỗi trong java là 2147483647.

Kiểu dữ liệu nguyên thủy int là 4 byte (32 bit) trong java. 1 bit (MSB) được sử dụng làm bit dấu , Phạm vi bị giới hạn trong khoảng -2 ^ 31 đến 2 ^ 31-1 (-2147483648 đến 2147483647). Chúng tôi không thể sử dụng các giá trị âm để lập chỉ mục. Rõ ràng phạm vi chúng tôi có thể sử dụng là từ 0 đến 2147483647.

|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.