जवाबों:
Stringकक्षा की lengthविधि को ध्यान में रखते हुए int, एक अधिकतम लंबाई जो विधि द्वारा वापस आ जाएगी Integer.MAX_VALUE, वह होगी 2^31 - 1(या लगभग 2 बिलियन)।
लंबाई और सरणियों का अनुक्रमण, (जैसे कि के संदर्भ में char[], जो संभवत: जिस तरह से आंतरिक डेटा प्रतिनिधित्व के लिए लागू किया गया है है Stringरों), अध्याय 10: सरणी के जावा भाषा विशिष्टता, जावा SE 7 संस्करण निम्नलिखित कहते हैं:
किसी सरणी में निहित चर का कोई नाम नहीं है; इसके बजाय वे ऐरे एक्सेस एक्सप्रेशन द्वारा संदर्भित होते हैं जो नॉनजेटिव पूर्णांक इंडेक्स मानों का उपयोग करते हैं। इन चर को सरणी का घटक कहा जाता है । यदि किसी सरणी में
nघटक होते हैं, तो हम कहते हैं कि सरणीnकी लंबाई है; सरणी के घटकों को समावेशी सूचकांकों से , समावेशी, का उपयोग करके संदर्भित किया0जाता हैn - 1।
इसके अलावा, अनुक्रमणिका intमूल्यों द्वारा होनी चाहिए , जैसा कि धारा 10.4 में उल्लिखित है :
intमूल्यों द्वारा अनुक्रमित किया जाना चाहिए ;
इसलिए, ऐसा प्रतीत होता है कि सीमा वास्तव में है 2^31 - 1, क्योंकि यह एक गैर- intमूल्य के लिए अधिकतम मूल्य है।
हालांकि, संभवतः अन्य सीमाएं होने जा रही हैं, जैसे कि किसी सरणी के लिए अधिकतम आवंटन योग्य आकार।
javac। उस शाब्दिक के बारे में एक त्रुटि देता है कि वह बहुत लंबा है:javac HelloWorld.java 2>&1|head -c 80 HelloWorld.java:3: constant string too long
javacलिए एक सीमा की तरह लगता है , क्योंकि मुझे जावा भाषा विनिर्देश और जेवीएम विशिष्टता में शाब्दिक आकार की सीमाओं का कोई संदर्भ नहीं मिल सकता है । मैंने एक शाब्दिक बनाने की कोशिश की जो 100,000 वर्णों से बड़ा था, और ग्रहण संकलक को इसे संकलित करने में कोई समस्या नहीं थी। (और कार्यक्रम को चलाने में यह दिखाने में सक्षम था कि शाब्दिक 100,000 से बड़ा था ।)String StringStringStringString.length
java.io.DataInput.readUTF()और java.io.DataOutput.writeUTF(String)कहते हैं कि एक Stringवस्तु को लंबाई की जानकारी के दो बाइट्स और स्ट्रिंग में प्रत्येक वर्ण के संशोधित UTF-8 का प्रतिनिधित्व किया जाता है। यह निष्कर्ष निकालता है कि स्ट्रिंग की लंबाई संशोधित UTF-8 स्ट्रिंग के बाइट्स की संख्या द्वारा सीमित है जब इसके साथ प्रयोग किया जाता है DataInputऔर DataOutput।
इसके अलावा, के विनिर्देशCONSTANT_Utf8_info जावा आभासी मशीन विनिर्देश में पाया के रूप में इस संरचना को परिभाषित करता है।
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
आप पा सकते हैं कि 'लंबाई' का आकार दो बाइट्स है ।
कि एक निश्चित विधि (जैसे String.length()) का वापसी प्रकार intहमेशा इसका मतलब नहीं है कि इसकी अनुमत अधिकतम मान है Integer.MAX_VALUE। इसके बजाय, ज्यादातर मामलों में, intकेवल प्रदर्शन कारणों के लिए चुना जाता है। जावा लैंग्वेज स्पेसिफिकेशन कहता है कि पूर्णांकों का आकार उससे छोटा होता है जो गणना intसे intपहले परिवर्तित हो जाते हैं (यदि मेरी मेमोरी मुझे सही ढंग से काम करती है) और यह intतब चुनने का एक कारण है जब कोई विशेष कारण न हो।
संकलन समय पर अधिकतम लंबाई अधिकतम 65536 है। ध्यान दें कि लंबाई संशोधित UTF-8 प्रतिनिधित्व के बाइट्स की संख्या है , न कि किसी Stringवस्तु में वर्णों की संख्या ।
Stringऑब्जेक्ट रनटाइम पर बहुत अधिक वर्ण रखने में सक्षम हो सकते हैं। हालाँकि, यदि आप Stringऑब्जेक्ट्स को इंटरफेस DataInputऔर DataOutputइंटरफेस के साथ उपयोग करना चाहते हैं, तो बहुत लंबी Stringवस्तुओं का उपयोग करने से बचना बेहतर है । जब मैं का ऑब्जेक्टिव-सी समकक्ष कार्यान्वित मैं इस सीमा पाया DataInput.readUTF()और DataOutput.writeUTF(String)।
चूंकि सरणियों को पूर्णांक के साथ अनुक्रमित किया जाना चाहिए, एक सरणी की अधिकतम लंबाई है Integer.MAX_INT(2 31 -1, या 2 147 483 647)। यह मान लिया गया है कि आपके पास उस आकार की एक सरणी रखने के लिए पर्याप्त मेमोरी है, निश्चित रूप से।
मेरे पास 8GB रैम के साथ 2010 iMac है, जावा 1.8.0_25 के साथ एक्लिप्स नियॉन .2 रिलीज़ (4.6.2) चल रहा है। VM तर्क -Xmx6g के साथ, मैंने निम्न कोड चलाया:
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());
यह प्रिंट:
Requested array size exceeds VM limit
1207959550
तो, ऐसा लगता है कि अधिकतम सरणी आकार ~ 1,207,959,549 है। तब मुझे एहसास हुआ कि अगर वास्तव में जावा मेमोरी से बाहर निकलता है तो हमें परवाह नहीं है: हम सिर्फ अधिकतम सरणी आकार (जो एक निरंतर परिभाषित किया गया लगता है) की तलाश कर रहे हैं। इसलिए:
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);
}
}
कौन सा प्रिंट:
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
तो, ऐसा लगता है कि अधिकतम Integer.MAX_VALUE - 2, या (2 ^ 31) - 3 है
PS मुझे यकीन नहीं है कि मेरा StringBuilderअधिकतम 1207959550समय क्यों निकल गया जबकि मेरी char[]अधिकतम संख्या 2 (31 ^ 31) -3 थी। ऐसा लगता है कि इसे विकसित करने के लिए AbstractStringBuilderइसके आंतरिक के आकार को दोगुना कर char[]दिया गया है, जिससे संभवत: यह मुद्दा बनता है।
स्ट्रिंग वर्ग की लंबाई () विधि का रिटर्न प्रकार इंट है ।
सार्वजनिक int लंबाई ()
Http://docs.oracle.com/javase/7/docs/api/java/lang/String.html##ength () देखें
तो इंट का अधिकतम मूल्य 2147483647 है ।
स्ट्रिंग को आंतरिक रूप से चार सरणी के रूप में माना जाता है, इसलिए अधिकतम सीमा के भीतर अनुक्रमण किया जाता है। इसका मतलब है कि हम 2147483648 वें सदस्य को अनुक्रमित नहीं कर सकते हैं। जावा में स्ट्रिंग की अधिकतम लंबाई 2147483647 है।
आदिम डेटा प्रकार int java में 4 बाइट्स (32 बिट्स) है। 1 बिट (MSB) का उपयोग साइन बिट के रूप में किया जाता है , रेंज -2 ^ 31 से 2 ^ 31-1 (-2147483648 से 2148483647) के लिए विवश है। हम अनुक्रमण के लिए नकारात्मक मान का उपयोग नहीं कर सकते हैं। जाहिर है कि हम जिस सीमा का उपयोग कर सकते हैं वह 0 से 2147483647 तक है।
जैसा कि ताकाहिको कावासाकी के उत्तर में उल्लेख किया गया है , जावा संशोधित यूटीएफ -8 के रूप में यूनिकोड के तारों का प्रतिनिधित्व करता है और जेवीएम-कल्पना CONSTANT_UTF8_info संरचना में , 2 बाइट्स को लंबाई में आवंटित किया जाता है (और स्ट्रिंग के पात्रों की संख्या नहीं)।
उत्तर का विस्तार करने के लिए, ASM jvm bytecode लाइब्रेरी की putUTF8विधि , में यह शामिल है:
public ByteVector putUTF8(final String stringValue) {
int charLength = stringValue.length();
if (charLength > 65535) {
// If no. of characters> 65535, than however UTF-8 encoded length, wont fit in 2 bytes.
throw new IllegalArgumentException("UTF8 string too large");
}
for (int i = 0; i < charLength; ++i) {
char charValue = stringValue.charAt(i);
if (charValue >= '\u0001' && charValue <= '\u007F') {
// Unicode code-point encoding in utf-8 fits in 1 byte.
currentData[currentLength++] = (byte) charValue;
} else {
// doesnt fit in 1 byte.
length = currentLength;
return encodeUtf8(stringValue, i, 65535);
}
}
...
}
लेकिन जब कोड-पॉइंट मैपिंग> 1byte, यह कॉल encodeUTF8विधि:
final ByteVector encodeUtf8(final String stringValue, final int offset, final int maxByteLength /*= 65535 */) {
int charLength = stringValue.length();
int byteLength = offset;
for (int i = offset; i < charLength; ++i) {
char charValue = stringValue.charAt(i);
if (charValue >= 0x0001 && charValue <= 0x007F) {
byteLength++;
} else if (charValue <= 0x07FF) {
byteLength += 2;
} else {
byteLength += 3;
}
}
...
}
इस अर्थ में, अधिकतम स्ट्रिंग लंबाई 65535 बाइट्स है, यानी utf-8 एन्कोडिंग लंबाई। और charगिनती न करें
आप उपरोक्त utf8 संरचना लिंक से JVM की संशोधित-यूनिकोड कोड-पॉइंट रेंज पा सकते हैं।
Stringसैद्धांतिक रूप से हैInteger.MAX_VALUE, स्रोत में एक स्ट्रिंग शाब्दिक की लंबाई UTF-8 डेटा के केवल 65535 बाइट्स तक सीमित प्रतीत होती है ।