2016-05-17 25 views
2

Ich versuche, Strings von Dateien direkt zu deserialisieren und ich habe eine Frage über sehr lange Strings: Java Strings haben eine Anzahl von Zeichen gleich Integer.MAX_VALUE, die 31^2-1 ist.Java String UTF-8 Grenzen

Aber hier kommt meine Frage: Was passiert, wenn ich einen UTF-8 String mit etwas weniger als dieser Größe habe, aber von Zeichen mit einer Größe von mehr als 1 Byte gebildet wird und dann frage ich Java das Byte-Array?

Um es klarer zu machen, was passiert, wenn ich diesen Code ausführen könnte? (Ich habe nicht genügend RAM):

String toPrint = ""; 
String string100 = ""; 
int max = Integer.MAX_VALUE -100; 
for (int i = 0; i < 100; i += 10) { 
    string100 += "1234567ñ90"; 
} 
for (int i = 0; i < max; i += 100) { 
    toPrint += string100; 
} 
System.out.println("String complete!"); 
byte[] byteArray = toPrint.getBytes(StandardCharsets.UTF_8); 
System.out.println(byteArray.length); 
System.exit(0); 

Wird "String complete!" Gedruckt? Oder bricht es vorher?

Antwort

3

Grundsätzlich ist die Grenze auf Strings dass die char Arrays in ihnen nicht länger als die maximale Feldlänge werden können, die in etwa maxInteger.MAX_VALUE und größer als der variabel ist. Zeichenfolgen speichern ihre Zeichen in UTF-16 und daher kann die UTF-16-Darstellung einer Zeichenfolge die maximale Array-Länge nicht überschreiten. Die Anzahl der Bytes in UTF-8 und die Anzahl der logischen Zeichen (Unicode-Codepunkte oder UTF-32-Zeichen) spielen letztlich keine Rolle.

Jetzt gehen wir zu Ihrem speziellen Beispiel. Da jedes der 10 Zeichen in "1234567ñ90" ein einzelner UTF-16-Wert ist, nimmt diese Zeichenfolge 10 Werte eines char Array String auf. Trotz der schrecklichen Leistung Ihres Codes und der hohen Speicheranforderungen sollte es schließlich zu "String complete" kommen. wenn genügend verfügbarer Speicher vorhanden ist. Es wird jedoch bei der Konvertierung in UTF-8 unterbrochen, da die UTF-8-Darstellung der Zeichenfolge länger als die maximale Array-Länge ist, da "ñ" mehr als ein Byte benötigt.

+0

Ich stimme der schrecklichen Leistung zu, es ist nur ein Beweis für das Konzept XD – nicovell3

+0

Aber dann, wie kann Java serialisieren und deserialisieren? Da Java ein UTF-8-Array zum Serialisieren verwendet ... – nicovell3

+0

@ nicovell3 Wenn die String-Serialisierung "String.getBytes (UTF-8)" aufruft, schlägt sie fehl. Wenn es nicht fehlschlägt, wird eine andere Methode zum Konvertieren in UTF-8 verwendet. –

0

Feldgröße ist auch beschränkt auf Integer.MAX_VALUE (weshalb String Größe begrenzt ist, doch es gibt eine char[] es sichern), so ist es unmöglich, das Byte-Array zu erhalten, wenn die Codierung mehr Bytes als das verwendet, egal, was die Größe des String ist in Zeichen. Das Endergebnis wäre ein OutOfMemoryError, aber das Erstellen der String an erster Stelle wäre erfolgreich.