[java] Java에서 문자열의 최대 길이-length () 메소드 호출
에서 자바 하는 최대 크기 무엇 String받는 참조 객체가 가질 수있는 length()메서드 호출?
나는 length()크기 를 반환 알고String 로 있다 char [].
답변
String클래스의 length메소드가를 반환한다는 것을 고려하면 int, 메소드가 반환하는 최대 길이 Integer.MAX_VALUE는 2^31 - 1약 20 억입니다.
(예 : 길이와 배열의 색인의 관점에서 char[]아마도 내부 데이터 표현이 구현되는 방식 인 String들), 제 10 장 : 배열 의 Java 언어 사양, 자바 SE 7 Edition은 다음을 말한다 :
배열에 포함 된 변수에는 이름이 없습니다. 대신 음이 아닌 정수 인덱스 값을 사용하는 배열 액세스 표현식에 의해 참조됩니다. 이러한 변수를 배열 의 구성 요소 라고합니다
. 배열에n구성 요소n가있는 경우 배열 의
길이 입니다. 배열의 구성 요소는에서0까지의 정수 색인을 사용하여 참조됩니다n - 1.
또한 10.4 절int 에서 언급 한 바와 같이 인덱싱은 값을 기준으로 해야합니다 .
배열은
int값 으로 색인화해야 합니다.
따라서 2^31 - 1음수가 아닌 최대 값이므로 한계가 실제로 나타납니다.int 값 .
그러나 배열의 할당 가능한 최대 크기와 같은 다른 제한 사항이있을 수 있습니다.
답변
java.io.DataInput.readUTF()및 java.io.DataOutput.writeUTF(String)있다고 String객체에 의해 표현되는 두 바이트 길이의 정보의 수정 UTF-8 스트링 내의 각 문자의 표현. 이는 String의 길이가 DataInputand 와 함께 사용될 때 문자열의 수정 된 UTF-8 표현의 바이트 수에 의해 제한된다는 결론을 내립니다 DataOutput.
또한, 의 사양CONSTANT_Utf8_info 은 다음과 같이 자바 가상 머신 스펙은 검색된 구조를 정의한다.
CONSTANT_Utf8_info {
u1 tag;
u2 length;
u1 bytes[length];
}
‘length’의 크기가 2 바이트 임을 알 수 있습니다 .
특정 방법 (예를 들면의 리턴 타입 그건 String.length())이다는 int항상 허용되는 최대 값입니다 의미하지 않는다 Integer.MAX_VALUE. 대신 대부분의 경우 int성능상의 이유로 선택됩니다. Java 언어 사양에 따르면 크기가 정수보다 작은 정수는 계산 전에 int변환됩니다 int(메모리가 올바르게 제공 int되는 경우) 특별한 이유가없는 경우 선택 해야하는 이유 중 하나 입니다.
컴파일 타임의 최대 길이는 최대 65536입니다. 길이는 오브젝트 의 문자 수가 아니라 수정 된 UTF-8 표현 의 바이트 수입니다 String.
String객체는 런타임에 훨씬 더 많은 문자를 가질 수 있습니다. 사용할 경우, String와 객체 DataInput및 DataOutput인터페이스를 너무 오래 사용하지 않는 것이 좋습니다 String객체. 이 I-C의 목표 등가물을 구현할 때이 제한을 발견 DataInput.readUTF()하고 DataOutput.writeUTF(String).
답변
배열은 정수로 색인화해야하므로 배열의 최대 길이는 Integer.MAX_INT(2 31 -1 또는 2 147 483 647)입니다. 이것은 물론 해당 크기의 배열을 보유하기에 충분한 메모리가 있다고 가정합니다.
답변
Java 1.8.0_25와 함께 Eclipse Neon.2 릴리스 (4.6.2)를 실행하는 8GB RAM의 2010 iMac이 있습니다. 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 인 것으로 보입니다. 그런 다음 Java에 메모리가 부족한 경우 실제로 신경 쓰지 않는다는 것을 깨달았습니다. 우리는 최대 배열 크기를 찾고 있습니다 (어딘가에 일정하게 정의 된 것처럼 보입니다). 그래서:
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
따라서 최대 값은 정수인 것 같습니다 .MAX_VALUE-2 또는 (2 ^ 31)-3
PS 잘 모르겠어요 왜 내 StringBuilder에서 끝나가는 밖으로 1207959550내 동안 char[](2 ^ 31)에 끝나가 -3입니다. AbstractStringBuilder내부 크기 가 두 배로 char[]커져서 문제가되는 것 같습니다.
답변
분명히 그것은 0x7FFFFFFF (2147483647) 인 int에 바인딩되어 있습니다.
답변
String 클래스의 length () 메소드의 리턴 유형은 int 입니다.
공개 int 길이 ()
보내다 http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#length ()를 하십시오.
따라서 int의 최대 값은 2147483647 입니다.
문자열은 내부적으로 char 배열로 간주되므로 인덱싱은 최대 범위 내에서 수행됩니다. 이것은 우리가 2147483648 번째 멤버를 인덱스 할 수 없다는 것을 의미합니다. 따라서 자바에서 String의 최대 길이는 2147483647입니다.
기본 데이터 유형 int는 java에서 4 바이트 (32 비트)입니다. 1 비트 (MSB)가 부호 비트로 사용되므로 범위는 -2 ^ 31에서 2 ^ 31-1 (-2147483648에서 2147483647)로 제한됩니다. 인덱싱에 음수 값을 사용할 수 없으므로 사용할 수있는 범위는 0에서 2147483647 사이입니다.
답변
Takahiko Kawasaki의 답변 에서 언급했듯이 java는 수정 된 UTF-8 형식의 유니 코드 문자열을 나타내며 JVM 사양 CONSTANT_UTF8_info Structure 에서 2 바이트는 길이에 할당되며 문자열의 문자 수는 아닙니다.
답을 확장하기 위해 ASM jvm 바이트 코드 라이브러리의 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);
}
}
...
}
그러나 코드 포인트 매핑이 1 바이트를 초과하면 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의 수정 된 유니 코드 코드 포인트 범위를 찾을 수 있습니다.
