I decided to read the JDK source somehow. That said, I don't have time to read each line carefully, so I read it briefly and found this code. Last time I read the source of Short, so next is Integer.
The Integer class is a wrapper class for the primitive type int. First, the fields and the constructor. Well, it's a source that everyone can imagine.
Integer.java
private final int value;
public Integer(int value) {
this.value = value;
}
Actually, there is an IntegerCache class that is not visible in javadoc.
Integer.java
/**
* 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. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
Byte, Short came and changed. Since this inner class is private, you can't usually read what is written in the javadoc comment. It seems that you can increase the upper limit from 127 with the startup option -XX: AutoBoxCacheMax = size. According to Numeric cache, it was added from JDK 1.6.
Let's check the source of JDK 1.5.
Integer.java
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
Oh, it's refreshing. Like Byte and Short, it was from -128 to 127. Although it is IntegerCache, it is referenced by valueOf like Byte and Short.
Integer.java
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
As with Short, compare the instances with 127 and 128.
Main.java
public static void main(String[] args) {
int i00 = 127;
Integer i01 = Integer.valueOf(i00);
Integer i02 = i00;
System.out.println(i01 == i02);
int i10 = 128;
Integer i11 = Integer.valueOf(i10);
Integer i12 = i10;
System.out.println(i11 == i12);
}
When you run ...
$ java Main
true
false
$ java -XX:AutoBoxCacheMax=127 Main
true
false
$ java -XX:AutoBoxCacheMax=128 Main
true
true
Boot option -XX: AutoBoxCacheMax is working.
In the Japanese translation of javadoc, "Notes on implementation: The implementation of the" bit twiddling "method (highestOneBit and numberOfTrailingZeros) is" Hacker's Delight "(Addison Wesley, 2002) by Henry S. Warren, Jr. ) It is based on. "is what it reads. Since it's from JDK 1.5, many of you probably know it, but let's search the source for the "HD" string.
Integer.java
public static int highestOneBit(int i) {
// HD, Figure 3-1
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
public static int numberOfLeadingZeros(int i) {
// HD, Figure 5-6
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
public static int numberOfTrailingZeros(int i) {
// HD, Figure 5-14
int y;
if (i == 0) return 32;
int n = 31;
y = i <<16; if (y != 0) { n = n -16; i = y; }
y = i << 8; if (y != 0) { n = n - 8; i = y; }
y = i << 4; if (y != 0) { n = n - 4; i = y; }
y = i << 2; if (y != 0) { n = n - 2; i = y; }
return n - ((i << 1) >>> 31);
}
public static int bitCount(int i) {
// HD, Figure 5-2
i = i - ((i >>> 1) & 0x55555555);
i = (i & 0x33333333) + ((i >>> 2) & 0x33333333);
i = (i + (i >>> 4)) & 0x0f0f0f0f;
i = i + (i >>> 8);
i = i + (i >>> 16);
return i & 0x3f;
}
public static int reverse(int i) {
// HD, Figure 7-1
i = (i & 0x55555555) << 1 | (i >>> 1) & 0x55555555;
i = (i & 0x33333333) << 2 | (i >>> 2) & 0x33333333;
i = (i & 0x0f0f0f0f) << 4 | (i >>> 4) & 0x0f0f0f0f;
i = (i << 24) | ((i & 0xff00) << 8) |
((i >>> 8) & 0xff00) | (i >>> 24);
return i;
}
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31) | (-i >>> 31);
}
bitCount feels like a bit when you look at the Algorithm for counting / searching bits. It seems to be much faster than looping and counting by yourself. When do you use the problem ... highestOneBit was solving the problem and I had the opportunity to use it. → Xmas Contest 2016 / A --Array Sum
There are quite a lot, so I picked up only three.
Integer.java
public static int sum(int a, int b) {
return a + b;
}
public static int max(int a, int b) {
return Math.max(a, b);
}
public static int min(int a, int b) {
return Math.min(a, b);
}
I don't really need it. If you want to make it anyway, you should make an int version of Math.pow (). (1/13 postscript) Well, if it is sum, if it is a method that has devised such as skipping an exception when it overflows, it is still worth the existence, but what about a method that just returns a + b? And since it's an Integer class, non-static methods like Integer add (Integer other) come in nicely ... (1/13 postscript) @see java.util.function.BinaryOperator is written in the javadoc comment, but did it make sense?
(1/13 postscript) I skipped it lightly, but I added it by looking at Long.parseUnsignedLong.
Starting with JDK 1.8, parseUnsignedInt has been added. Isn't java int signed? What does it mean to parse it unsigned?
Integer.java
public static int parseUnsignedInt(String s, int radix)
throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
int len = s.length();
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar == '-') {
throw new
NumberFormatException(String.format("Illegal leading minus sign " +
"on unsigned string %s.", s));
} else {
if (len <= 5 || // Integer.MAX_VALUE in Character.MAX_RADIX is 6 digits
(radix == 10 && len <= 9) ) { // Integer.MAX_VALUE in base 10 is 10 digits
return parseInt(s, radix);
} else {
long ell = Long.parseLong(s, radix);
if ((ell & 0xffff_ffff_0000_0000L) == 0) {
return (int) ell;
} else {
throw new
NumberFormatException(String.format("String value %s exceeds " +
"range of unsigned int.", s));
}
}
}
} else {
throw NumberFormatException.forInputString(s);
}
}
I wondered if I could write 0xffff_ffff_0000_0000L, but if it was a value of only the lower 32 bits, I would cast it with an int. In other words, even if the sign bit is set, it will be cast as an int, so it will be negative. It parses unsigned, but it can be negative. It's a great specification.
Let's try it.
Main.java
public static void main(String[] args) {
int i01 = Integer.parseUnsignedInt("2147483647");
System.out.println(i01);
int i02 = Integer.parseUnsignedInt("2147483648");
System.out.println(i02);
int i03 = Integer.parseUnsignedInt("4294967295");
System.out.println(i03);
int i04 = Integer.parseUnsignedInt("4294967296");
System.out.println(i04);
}
When you run ...
2147483647
-2147483648
-1
Exception in thread "main" java.lang.NumberFormatException: String value 4294967296 exceeds range of unsigned int.
at java.lang.Integer.parseUnsignedInt(Integer.java:684)
at java.lang.Integer.parseUnsignedInt(Integer.java:711)
at Main.main(Main.java:9)
The result is as expected, but are you happy? this. If you want to use 32-bit full, you can use long.
There is parseUnsignedInt in the methods added in JDK 1.8, but I feel that there are many static methods. (1/13 postscript) There were 37 public static methods in JDK 1.8. I think it would be better to separate it into the IntegerUtil class if there is such a thing. By the way, it was 13 in JDK 1.4. Once upon a time I thought it was a simpler class.
Suddenly I noticed that the hard tab width is supposed to be 4 characters. Once upon a time, the width of the hard tab was 8 characters, one indent was 4 blanks, 2 indents were 1 hard tab, 3 indents were 1 hard tab + 4 blanks, and 4 indents were 2 hard tabs.
Comparing the old sauces, --JDK 1.4 Sun Microsystems Hard tab 8 characters --JDK 1.5 Sun Microsystems Hard tab 8 characters --JDK 1.6 Oracle Hardtab 8 characters --JDK 1.7 Oracle Hard Tab 4 Characters --JDK 1.8 Oracle Hardtab 4 characters And the style has changed from JDK 1.7. (1/13 postscript) I thought that the hard tab width of 8 characters would be about assembly language, so I replaced all the hard tabs with 8 blank characters. I thought Sun Microsystems was a good company, but I've always thought that this style was crazy.
(1/13 postscript) I grep, so paste it public static String toString(int i, int radix) { public static String toUnsignedString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static String toUnsignedString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static int parseUnsignedInt(String s, int radix) public static int parseUnsignedInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException { public static Integer valueOf(int i) { public static int hashCode(int value) { public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException { public static int compare(int x, int y) { public static int compareUnsigned(int x, int y) { public static long toUnsignedLong(int x) { public static int divideUnsigned(int dividend, int divisor) { public static int remainderUnsigned(int dividend, int divisor) { public static int highestOneBit(int i) { public static int lowestOneBit(int i) { public static int numberOfLeadingZeros(int i) { public static int numberOfTrailingZeros(int i) { public static int bitCount(int i) { public static int rotateLeft(int i, int distance) { public static int rotateRight(int i, int distance) { public static int reverse(int i) { public static int signum(int i) { public static int reverseBytes(int i) { public static int sum(int a, int b) { public static int max(int a, int b) { public static int min(int a, int b) {
(1/13 postscript) I grep, so paste it public static String toString(int i, int radix) { public static String toHexString(int i) { public static String toOctalString(int i) { public static String toBinaryString(int i) { public static String toString(int i) { public static int parseInt(String s, int radix) public static int parseInt(String s) throws NumberFormatException { public static Integer valueOf(String s, int radix) throws NumberFormatException { public static Integer valueOf(String s) throws NumberFormatException public static Integer getInteger(String nm) { public static Integer getInteger(String nm, int val) { public static Integer getInteger(String nm, Integer val) { public static Integer decode(String nm) throws NumberFormatException {
Recommended Posts