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 String
là a char []
;
Helpex - Trao Đổi & Giúp Đỡ - là một trang web tổng hợp, chia sẻ kiến thức và hỏi đáp dành cho các lĩnh vực ở mọi cấp độ và các chuyên gia trong các lĩnh vực liên quan. Chỉ mất một phút để đăng ký.
Tham gia cộng đồngTrong 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 String
là a char []
;
Xem xét phương thức String
của lớp length
trả về một int
, độ dài tối đa mà phương thức sẽ trả về sẽ Integer.MAX_VALUE
là 2^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 String
s), 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ó
n
các thành phần, chúng ta nóin
là chiề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
đếnn - 1
, bao gồm.
Hơn nữa, việc lập chỉ mục phải theo int
các giá trị, như được đề cập trong Phần 10.4 :
Mảng phải được lập chỉ mục bởi
int
cá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 int
giá 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.
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/2009Tô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
@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 String
chữ trong Đặc tả ngôn ngữ Java và Đặc tả JVM. Tôi đã thử tạo một String
ký 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.length
lớn hơn 100.000.)
@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/2012java.io.DataInput.readUTF()
và 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 DataInput
và DataOutput
.
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()
) int
khô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 int
trướ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 int
khi 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.
String
cá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 String
các đối tượng DataInput
và DataOutput
giao diện, tốt hơn là tránh sử dụng String
cá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()
và DataOutput.writeUTF(String)
.
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 đó.
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 StringBuilder
tối đa của tôi lại 1207959550
trong khi char[]
tối đa của tôi ở (2 ^ 31) -3. Có vẻ như AbstractStringBuilder
tă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 đề.
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.
Mặc dù
– Đỗ Thụy Ðào 05:46:37 13/11/2013String
về mặt lý thuyếtInteger.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.