src/java.base/share/classes/java/lang/Integer.java
Print this page
@@ -27,10 +27,14 @@
import java.lang.annotation.Native;
import java.util.Objects;
import jdk.internal.HotSpotIntrinsicCandidate;
+import static java.lang.String.COMPACT_STRINGS;
+import static java.lang.String.LATIN1;
+import static java.lang.String.UTF16;
+
/**
* The {@code Integer} class wraps a value of the primitive type
* {@code int} in an object. An object of type {@code Integer}
* contains a single field whose type is {@code int}.
*
@@ -136,29 +140,51 @@
/* Use the faster version */
if (radix == 10) {
return toString(i);
}
- char buf[] = new char[33];
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[33];
boolean negative = (i < 0);
int charPos = 32;
if (!negative) {
i = -i;
}
while (i <= -radix) {
- buf[charPos--] = digits[-(i % radix)];
+ buf[charPos--] = (byte)digits[-(i % radix)];
i = i / radix;
}
- buf[charPos] = digits[-i];
+ buf[charPos] = (byte)digits[-i];
if (negative) {
buf[--charPos] = '-';
}
- return new String(buf, charPos, (33 - charPos));
+ return StringLatin1.newString(buf, charPos, (33 - charPos));
+ }
+ return toStringUTF16(i, radix);
+ }
+
+ private static String toStringUTF16(int i, int radix) {
+ byte[] buf = new byte[33 * 2];
+ boolean negative = (i < 0);
+ int charPos = 32;
+ if (!negative) {
+ i = -i;
+ }
+ while (i <= -radix) {
+ StringUTF16.putChar(buf, charPos--, digits[-(i % radix)]);
+ i = i / radix;
+ }
+ StringUTF16.putChar(buf, charPos, digits[-i]);
+
+ if (negative) {
+ StringUTF16.putChar(buf, --charPos, '-');
+ }
+ return StringUTF16.newString(buf, charPos, (33 - charPos));
}
/**
* Returns a string representation of the first argument as an
* unsigned integer value in the radix specified by the second
@@ -310,16 +336,20 @@
*/
private static String toUnsignedString0(int val, int shift) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
int mag = Integer.SIZE - Integer.numberOfLeadingZeros(val);
int chars = Math.max(((mag + (shift - 1)) / shift), 1);
- char[] buf = new char[chars];
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
-
- // Use special constructor which takes over "buf".
- return new String(buf, true);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[chars * 2];
+ formatUnsignedIntUTF16(val, shift, buf, 0, chars);
+ return new String(buf, UTF16);
+ }
}
/**
* Format an {@code int} (treated as unsigned) into a character buffer. If
* {@code len} exceeds the formatted ASCII representation of {@code val},
@@ -342,10 +372,32 @@
buf[--charPos] = Integer.digits[val & mask];
val >>>= shift;
} while (charPos > offset);
}
+ /** byte[]/LATIN1 version */
+ static void formatUnsignedInt(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ buf[--charPos] = (byte)Integer.digits[val & mask];
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
+ /** byte[]/UTF16 version */
+ static void formatUnsignedIntUTF16(int val, int shift, byte[] buf, int offset, int len) {
+ int charPos = offset + len;
+ int radix = 1 << shift;
+ int mask = radix - 1;
+ do {
+ StringUTF16.putChar(buf, --charPos, Integer.digits[val & mask]);
+ val >>>= shift;
+ } while (charPos > offset);
+ }
+
static final char [] DigitTens = {
'0', '0', '0', '0', '0', '0', '0', '0', '0', '0',
'1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
'2', '2', '2', '2', '2', '2', '2', '2', '2', '2',
'3', '3', '3', '3', '3', '3', '3', '3', '3', '3',
@@ -399,13 +451,19 @@
@HotSpotIntrinsicCandidate
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
- char[] buf = new char[size];
+ if (COMPACT_STRINGS) {
+ byte[] buf = new byte[size];
getChars(i, size, buf);
- return new String(buf, true);
+ return new String(buf, LATIN1);
+ } else {
+ byte[] buf = new byte[size * 2];
+ getCharsUTF16(i, size, buf);
+ return new String(buf, UTF16);
+ }
}
/**
* Returns a string representation of the argument as an unsigned
* decimal value.
@@ -431,11 +489,45 @@
* digit at the specified index (exclusive), and working
* backwards from there.
*
* Will fail if i == Integer.MIN_VALUE
*/
- static void getChars(int i, int index, char[] buf) {
+ static void getChars(int i, int index, byte[] buf) {
+ int q, r;
+ int charPos = index;
+ char sign = 0;
+
+ if (i < 0) {
+ sign = '-';
+ i = -i;
+ }
+
+ // Generate two digits per iteration
+ while (i >= 65536) {
+ q = i / 100;
+ // really: r = i - (q * 100);
+ r = i - ((q << 6) + (q << 5) + (q << 2));
+ i = q;
+ buf [--charPos] = (byte)DigitOnes[r];
+ buf [--charPos] = (byte)DigitTens[r];
+ }
+
+ // Fall thru to fast mode for smaller numbers
+ // assert(i <= 65536, i);
+ for (;;) {
+ q = (i * 52429) >>> (16+3);
+ r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
+ buf [--charPos] = (byte)digits [r];
+ i = q;
+ if (i == 0) break;
+ }
+ if (sign != 0) {
+ buf [--charPos] = (byte)sign;
+ }
+ }
+
+ static void getCharsUTF16(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
char sign = 0;
if (i < 0) {
@@ -447,25 +539,25 @@
while (i >= 65536) {
q = i / 100;
// really: r = i - (q * 100);
r = i - ((q << 6) + (q << 5) + (q << 2));
i = q;
- buf [--charPos] = DigitOnes[r];
- buf [--charPos] = DigitTens[r];
+ StringUTF16.putChar(buf, --charPos, DigitOnes[r]);
+ StringUTF16.putChar(buf, --charPos, DigitTens[r]);
}
// Fall thru to fast mode for smaller numbers
// assert(i <= 65536, i);
for (;;) {
q = (i * 52429) >>> (16+3);
r = i - ((q << 3) + (q << 1)); // r = i-(q*10) ...
- buf [--charPos] = digits [r];
+ StringUTF16.putChar(buf, --charPos, Integer.digits[r]);
i = q;
if (i == 0) break;
}
if (sign != 0) {
- buf [--charPos] = sign;
+ StringUTF16.putChar(buf, --charPos, sign);
}
}
static final int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
99999999, 999999999, Integer.MAX_VALUE };