--- a/jdk/src/share/classes/java/lang/Integer.java Tue Mar 24 14:03:46 2009 +0000
+++ b/jdk/src/share/classes/java/lang/Integer.java Tue Mar 24 14:05:44 2009 +0000
@@ -25,6 +25,8 @@
package java.lang;
+import java.util.Properties;
+
/**
* The {@code Integer} class wraps a value of the primitive type
* {@code int} in an object. An object of type {@code Integer}
@@ -442,6 +444,12 @@
public static int parseInt(String s, int radix)
throws NumberFormatException
{
+ /*
+ * WARNING: This method may be invoked early during VM initialization
+ * before IntegerCache is initialized. Care must be taken to not use
+ * the valueOf method.
+ */
+
if (s == null) {
throw new NumberFormatException("null");
}
@@ -545,7 +553,7 @@
* does not contain a parsable {@code int}.
*/
public static Integer valueOf(String s, int radix) throws NumberFormatException {
- return new Integer(parseInt(s,radix));
+ return Integer.valueOf(parseInt(s,radix));
}
/**
@@ -570,20 +578,56 @@
* @exception NumberFormatException if the string cannot be parsed
* as an integer.
*/
- public static Integer valueOf(String s) throws NumberFormatException
- {
- return new Integer(parseInt(s, 10));
+ public static Integer valueOf(String s) throws NumberFormatException {
+ return Integer.valueOf(parseInt(s, 10));
+ }
+
+ /**
+ * Cache to support the object identity semantics of autoboxing for values between
+ * -128 and 127 (inclusive) as required by JLS.
+ *
+ * The cache is initialized on first usage. During VM initialization the
+ * getAndRemoveCacheProperties method may be used to get and remove any system
+ * properites that configure the cache size. At this time, the size of the
+ * cache may be controlled by the -XX:AutoBoxCacheMax=<size> option.
+ */
+
+ // value of java.lang.Integer.IntegerCache.high property (obtained during VM init)
+ private static String integerCacheHighPropValue;
+
+ static void getAndRemoveCacheProperties() {
+ if (!sun.misc.VM.isBooted()) {
+ Properties props = System.getProperties();
+ integerCacheHighPropValue =
+ (String)props.remove("java.lang.Integer.IntegerCache.high");
+ if (integerCacheHighPropValue != null)
+ System.setProperties(props); // remove from system props
+ }
}
private static class IntegerCache {
- private IntegerCache(){}
-
- static final Integer cache[] = new Integer[-(-128) + 127 + 1];
+ static final int low = -128;
+ static final int high;
+ static final Integer cache[];
static {
- for(int i = 0; i < cache.length; i++)
- cache[i] = new Integer(i - 128);
+ // high value may be configured by property
+ int h = 127;
+ if (integerCacheHighPropValue != null) {
+ int i = parseInt(integerCacheHighPropValue);
+ i = Math.max(i, 127);
+ // Maximum array size is Integer.MAX_VALUE
+ h = Math.min(i, Integer.MAX_VALUE - (-low));
+ }
+ high = h;
+
+ cache = new Integer[(high - low) + 1];
+ int j = low;
+ for(int k = 0; k < cache.length; k++)
+ cache[k] = new Integer(j++);
}
+
+ private IntegerCache() {}
}
/**
@@ -599,10 +643,9 @@
* @since 1.5
*/
public static Integer valueOf(int i) {
- final int offset = 128;
- if (i >= -128 && i <= 127) { // must cache
- return IntegerCache.cache[i + offset];
- }
+ assert IntegerCache.high >= 127;
+ if (i >= IntegerCache.low && i <= IntegerCache.high)
+ return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
@@ -806,7 +849,7 @@
*/
public static Integer getInteger(String nm, int val) {
Integer result = getInteger(nm, null);
- return (result == null) ? new Integer(val) : result;
+ return (result == null) ? Integer.valueOf(val) : result;
}
/**
@@ -938,7 +981,7 @@
try {
result = Integer.valueOf(nm.substring(index), radix);
- result = negative ? new Integer(-result.intValue()) : result;
+ result = negative ? Integer.valueOf(-result.intValue()) : result;
} catch (NumberFormatException e) {
// If number is Integer.MIN_VALUE, we'll end up here. The next line
// handles this case, and causes any genuine format error to be
--- a/jdk/src/share/classes/java/lang/Long.java Tue Mar 24 14:03:46 2009 +0000
+++ b/jdk/src/share/classes/java/lang/Long.java Tue Mar 24 14:05:44 2009 +0000
@@ -510,7 +510,7 @@
* contain a parsable {@code long}.
*/
public static Long valueOf(String s, int radix) throws NumberFormatException {
- return new Long(parseLong(s, radix));
+ return Long.valueOf(parseLong(s, radix));
}
/**
@@ -537,7 +537,7 @@
*/
public static Long valueOf(String s) throws NumberFormatException
{
- return new Long(parseLong(s, 10));
+ return Long.valueOf(parseLong(s, 10));
}
private static class LongCache {
@@ -650,7 +650,7 @@
try {
result = Long.valueOf(nm.substring(index), radix);
- result = negative ? new Long(-result.longValue()) : result;
+ result = negative ? Long.valueOf(-result.longValue()) : result;
} catch (NumberFormatException e) {
// If number is Long.MIN_VALUE, we'll end up here. The next line
// handles this case, and causes any genuine format error to be
@@ -869,7 +869,7 @@
*/
public static Long getLong(String nm, long val) {
Long result = Long.getLong(nm, null);
- return (result == null) ? new Long(val) : result;
+ return (result == null) ? Long.valueOf(val) : result;
}
/**
--- a/jdk/src/share/classes/java/lang/System.java Tue Mar 24 14:03:46 2009 +0000
+++ b/jdk/src/share/classes/java/lang/System.java Tue Mar 24 14:05:44 2009 +0000
@@ -1105,6 +1105,13 @@
props = new Properties();
initProperties(props);
sun.misc.Version.init();
+
+ // Gets and removes system properties that configure the Integer
+ // cache used to support the object identity semantics of autoboxing.
+ // At this time, the size of the cache may be controlled by the
+ // -XX:AutoBoxCacheMax=<size> option.
+ Integer.getAndRemoveCacheProperties();
+
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);
FileOutputStream fdOut = new FileOutputStream(FileDescriptor.out);
FileOutputStream fdErr = new FileOutputStream(FileDescriptor.err);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/lang/Integer/ValueOf.java Tue Mar 24 14:05:44 2009 +0000
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/**
+ * @test
+ * @bug 6807702
+ * @summary Basic test for Integer.valueOf
+ * @run main ValueOf
+ * @run main/othervm -esa -XX:+AggressiveOpts ValueOf
+ */
+
+public class ValueOf {
+
+ // test Integer.valueOf over this range (inclusive)
+ private static final int TEST_LOW = -1024;
+ private static final int TEST_HIGH = 24576;
+
+ public static void main(String[] args) {
+ int i = TEST_LOW;
+ while (i <= TEST_HIGH) {
+ // check that valueOf stores i
+ if (Integer.valueOf(i).intValue() != i)
+ throw new RuntimeException();
+
+ // check that the same object is returned for integral values
+ // in the range -128 to 127 (inclusive)
+ if (i >= -128 && i <= 127) {
+ if (Integer.valueOf(i) != Integer.valueOf(i))
+ throw new RuntimeException();
+ }
+
+ i++;
+ }
+ }
+}