概述
Java是一种强类型语言,必须为每一种变量声明一种类型.在Java中一共有8种基本类型(primitive type),其中有4中整型,2种浮点类型,1中用于表示Unicode编码的字符单元的字符类型char和一种用于真值表示的boolean类型
之前曾写过几篇博文
这些博文大都是在JVM或者计算机组成原理相关角度来看待的。
最近要开始阅读JDK的源码了,希望能够从源码角度回顾这些内容
下面会从这8种基本类型(primitive type)对应的包装器类型进行解析
布尔类型之所以未定 是因为JVM中没有boolean类型
下面会从这8种基本类型(primitive type)对应的包装器类型进行解析
public final class Integer extends Number implements Comparable
public final class Double extends Number implements Comparable
public final class Float extends Number implements Comparable
public final class Long extends Number implements Comparable
public final class Byte extends Number implements Comparable
public final class Short extends Number implements Comparable
public final class Boolean implements Serializable, Comparable
public final class Character implements java.io.Serializable, Comparable
数值类型的包装器都继承了Number抽象类且实现了Comparable的接口方法
而对于Boolean和Character,它们都实现了Serializable和Comparable的接口方法
java.io.Serializable和Serializable是同一个接口
如果要剖析它们的包装类 首先要从Number抽象类和Comparable接口入手
Comparable接口
Comparable是内部比较器,常用作自然排序接口,需要实现内部的compareTo方法
源代码
package java.lang;
import java.util.List;
public interface Comparable {
int compareTo(T o);
}
内部比较器的特点是嵌入式的 , 其比较行为必须在待比较对象内部实现。
一个类如果实现了Comparable接口,就意味着“该类本身支持排序”,并且可以直接通过Arrays.sort()或Collections.sort()进行排序
当然,一个类如果没有实现Comparable接口,也可以挂载外部比较器Comparator进行排序
一般来说
通过 x.compareTo(y) 来“比较x和y的大小
返回“负数”,意味着“x
返回“零”,意味着“x==y”
返回“正数”,意味着“x>y”
具体的实现要结合后面的源代码
Number抽象类
Number 类定义了一些抽象方法,以各种不同数字格式返回对象的值。如 xxxValue() 方法,它将 Number 对象转换为 xxx 数据类型的值并返回,其中 doubleValue() 方法返回 double 类型的值,floatValue() 方法返回 float 类型的值。
该抽象类声明了各种包装类型的拆箱方法
package java.lang;
import java.io.Serializable;
// 数值类型包装类的共同祖先,声明了各种包装类型的拆箱方法
public abstract class Number implements Serializable {
private static final long serialVersionUID = -8742448824652078965L;
// 以byte形式返回当前对象的值
public byte byteValue() {
return (byte) intValue();
}
// 以short形式返回当前对象的值
public short shortValue() {
return (short) intValue();
}
// 以int形式返回当前对象的值
public abstract int intValue();
// 以long形式返回当前对象的值
public abstract long longValue();
// 以float形式返回当前对象的值
public abstract float floatValue();
// 以double形式返回当前对象的值
public abstract double doubleValue();
}
包装类
这里以Integer类为例进行解析,其他数值类型的包装类与此类似
字段部分
@Native
private static final long serialVersionUID = 1360826667806852920L;
// 相当于int.class
@SuppressWarnings("unchecked")
public static final Class TYPE = (Class) Class.getPrimitiveClass("int");
关于@SuppressWarnings注解
作用:告诉编译器忽略指定的警告,不用在编译完成后出现警告信息。
其中 @SuppressWarnings(“unchecked”),告诉编译器忽略 unchecked 警告信息,如使用List,ArrayList等未进行参数化产生的警告信息。
代码中注释 “相当于int.class”
实际上是这样的 ,为了获取基本数据类型int
可以通过Class.getPrimitiveClass(“int”)获取int.class类型
@Native
public static final int MIN_VALUE = 0x80000000; // int最小值 0
//二进制为 10000000 00000000 00000000 00000000
@Native
public static final int MAX_VALUE = 0x7fffffff; // int最大值
//二进制为 01111111 11111111 11111111 11111111
@Native
public static final int SIZE = 32; // 当前类型所占bit[位]数
//JVM中int类型为4个字节 32位
public static final int BYTES = SIZE / Byte.SIZE; // 当前类型所占字节数
private final int value; // 当前类包装的值
// 进制
static final char[] digits = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'a', 'b', 'c', 'd', 'e', 'f', 'g',
'h', 'i', 'j', 'k', 'l', 'm', 'n',
'o', 'p', 'q', 'r', 's', 't',
'u', 'v', 'w', 'x', 'y', 'z'
};
// 个位数
static final byte[] DigitOnes = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
};
// 十位数
static final byte[] 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',
'4', '4', '4', '4', '4', '4', '4', '4', '4', '4',
'5', '5', '5', '5', '5', '5', '5', '5', '5', '5',
'6', '6', '6', '6', '6', '6', '6', '6', '6', '6',
'7', '7', '7', '7', '7', '7', '7', '7', '7', '7',
'8', '8', '8', '8', '8', '8', '8', '8', '8', '8',
'9', '9', '9', '9', '9', '9', '9', '9', '9', '9',
};
// Left here for compatibility reasons, see JDK-8143900.
//出于兼容性的原因留在这里
static final int[] sizeTable = {9, 99, 999, 9999, 99999, 999999, 9999999, 99999999, 999999999, Integer.MAX_VALUE};
构造方法
@Deprecated(since = "9")
public Integer(int value) {
this.value = value;
}
@Deprecated(since = "9")
public Integer(String s) throws NumberFormatException {
this.value = parseInt(s, 10);
}
注解 @Deprecated 可以标记 Java API 状态,可以是以下几种:
使用它存在风险,可能导致错误
可能在未来版本中不兼容
可能在未来版本中删除
一个更好和更高效的方案已经取代它。
Java 9 中注解增加了两个新元素:since 和 forRemoval。
since: 元素指定已注解的API元素已被弃用的版本。
forRemoval: 元素表示注解的 API 元素在将来的版本中被删除,应该迁移 API。
普通方法
装箱
int --> Integer 默认的装箱行为
第一段 代码体现了享元设计模式
@HotSpotIntrinsicCandidate
public static Integer valueOf(int i) {
if(i >= IntegerCache.low && i<=IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
//这里的IntegerCache见下面
//这段代码体现了享元设计模式
// 按10进制形式将字符串s解析为int值,随后再装箱
public static Integer valueOf(String s) throws NumberFormatException {
return Integer.valueOf(parseInt(s, 10));
}
// 按radix进制形式将字符串s解析为int值,随后再装箱
public static Integer valueOf(String s, int radix) throws NumberFormatException {
return Integer.valueOf(parseInt(s, radix));
}
如果你对JVM解释执行和即时编译有了解,那么对于HotSpotIntrinsicCandidate注解很容易就能理解,表示这是段热点代码
可以参考【Java核心技术卷】谈谈对Java平台的理解
注意这里的valueOf方法 为下面的 decode等方法做了一些字符串转化成整型的准备
IntegerCache是属于Integer的静态内部类
它是Integer缓存,默认缓存了-128~127之间的Integer对象
如果想增加缓存数字的上限,比如将缓存范围改为[-128, 200],
则可以设置运行参数:
-XX:AutoBoxCacheMax=200
或
-Djava.lang.Integer.IntegerCache.high=200
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 = VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
//java.lang.Integer.IntegerCache.high是用来设置HotSpot VM上Integer的autobox(自动装箱缓存大小配置)范围的
//使用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); // [low, high]的个数不能超过Integer.MAX_VALUE
} 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[k] = new Integer(j++);
}
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {
}
}
}
将字符串nm解析为int,随后再装箱
采用哪种进制解析nm取决于nm的格式:
0x、0X、#开头,代表按16进制解析
0开头,代表按8进制解析
其他情形默认按10进制解析
public static Integer decode(String nm) throws NumberFormatException {
int radix = 10; //进制
int index = 0; //标记字符串开始比较的位置
boolean negative = false; //negative的意思是负数 false代表为正
Integer result; //结果封装成变量名为result的Integer对象
//判断是否为空字符串
if(nm.length() == 0)
throw new NumberFormatException("Zero length string");
//解析第一位 判断正负
char firstChar = nm.charAt(0);
if(firstChar == '-') {
negative = true;
index++;
} else if(firstChar == '+')
index++;
// Handle radix specifier, if present
//判断开头
//startWith(String s,int t) 测试在指定索引处t开始的此字符串的子字符串是否以指定的前缀s开头。
if(nm.startsWith("0x", index) || nm.startsWith("0X", index)) {
index += 2;
radix = 16;
} else if(nm.startsWith("#", index)) {
index++;
radix = 16;
} else if(nm.startsWith("0", index) && nm.length()>1 + index) {
index++;
radix = 8;
}
if(nm.startsWith("-", index) || nm.startsWith("+", index))
throw new NumberFormatException("Sign character in wrong position");
try {
result = Integer.valueOf(nm.substring(index), radix);
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
// rethrown.
String constant = negative ? ("-" + nm.substring(index)) : nm.substring(index);
result = Integer.valueOf(constant, radix);
}
return result;
}
拆箱
这里是重写了Number抽象类的方法 原理很简单 进行强制类型转换
// 以byte形式返回当前对象的值
public byte byteValue() {
return (byte) value;
}
// 以short形式返回当前对象的值
public short shortValue() {
return (short) value;
}
// Integer-->int 默认的拆箱行为
@HotSpotIntrinsicCandidate
public int intValue() {
return value;
}
// 以long形式返回当前对象的值
public long longValue() {
return (long) value;
}
// 以float形式返回当前对象的值
public float floatValue() {
return (float) value;
}
// 以double形式返回当前对象的值
public double doubleValue() {
return (double) value;
}
从属性中解析值
从系统属性中获取值,然后再装箱
其中,nm为某个系统属性,val为备用值
比如:
System.setProperty(“age”, “20”);
Integer x = getInteger(“age”, 25);
如果属性age存在(被提前设置),x的值为20。
如果属性age不存在,则x的值为备用值25。
public static Integer getInteger(String nm, Integer val) {
String v = null;
try {
v = System.getProperty(nm);
} catch(IllegalArgumentException | NullPointerException e) {
}
if(v != null) {
try {
return Integer.decode(v);
} catch(NumberFormatException e) {
}
}
return val;
}
// 从系统属性中获取值,然后再装箱。如果取不到值,选用val
public static Integer getInteger(String nm, int val) {
Integer result = getInteger(nm, null);
return (result == null) ? Integer.valueOf(val) : result;
}
// 从系统属性中获取值,然后再装箱。如果取不到值,返回null。
public static Integer getInteger(String nm) {
return getInteger(nm, null);
}
java的System.getProperty()方法可以获取的值
逆字符串化
功能分为:
按radix进制形式将字符串s解析为int值
按10进制形式将字符串s解析为int值
按radix进制形式将字符序列s的[beginIndex, endIndex)部分解析为int值
按radix进制形式将无符号整型字符串s解析为有符号整型值
按10进制形式将无符号整型字符串s解析为有符号整型值
按radix进制形式将无符号整型字符序列s的[beginIndex, endIndex)部分解析为有符号整型值
// 按radix进制形式将字符串s解析为int值
public static int parseInt(String s, int radix) throws NumberFormatException {
if(s == null) {
throw new NumberFormatException("null");
}
if(radix
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if(radix>Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
if(len>0) {
char firstChar = s.charAt(0);
if(firstChar
if(firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if(firstChar != '+') {
throw NumberFormatException.forInputString(s);
}
if(len == 1) { // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
}
i++;
}
int multmin = limit / radix;
int result = 0;
while(i
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i++), radix);
if(digit<0 || result
throw NumberFormatException.forInputString(s);
}
result *= radix;
if(result
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString(s);
}
}
// 按10进制形式将字符串s解析为int值
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s, 10);
}
// 按radix进制形式将字符序列s的[beginIndex, endIndex)部分解析为int值
public static int parseInt(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
s = Objects.requireNonNull(s);
if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
throw new IndexOutOfBoundsException();
}
if(radix
throw new NumberFormatException("radix " + radix + " less than Character.MIN_RADIX");
}
if(radix>Character.MAX_RADIX) {
throw new NumberFormatException("radix " + radix + " greater than Character.MAX_RADIX");
}
boolean negative = false;
int i = beginIndex;
int limit = -Integer.MAX_VALUE;
if(i
char firstChar = s.charAt(i);
if(firstChar
if(firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if(firstChar != '+') {
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
i++;
if(i == endIndex) { // Cannot have lone "+" or "-"
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
}
int multmin = limit / radix;
int result = 0;
while(i
// Accumulating negatively avoids surprises near MAX_VALUE
int digit = Character.digit(s.charAt(i), radix);
if(digit<0 || result
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
result *= radix;
if(result
throw NumberFormatException.forCharSequence(s, beginIndex, endIndex, i);
}
i++;
result -= digit;
}
return negative ? result : -result;
} else {
throw NumberFormatException.forInputString("");
}
}
// 按radix进制形式将无符号整型字符串s解析为有符号整型值
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);
}
}
// 按10进制形式将无符号整型字符串s解析为有符号整型值
public static int parseUnsignedInt(String s) throws NumberFormatException {
return parseUnsignedInt(s, 10);
}
// 按radix进制形式将无符号整型字符序列s的[beginIndex, endIndex)部分解析为有符号整型值
public static int parseUnsignedInt(CharSequence s, int beginIndex, int endIndex, int radix) throws NumberFormatException {
s = Objects.requireNonNull(s);
if(beginIndex<0 || beginIndex>endIndex || endIndex>s.length()) {
throw new IndexOutOfBoundsException();
}
int start = beginIndex, len = endIndex - beginIndex;
if(len>0) {
char firstChar = s.charAt(start);
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, start, start + len, radix);
} else {
long ell = Long.parseLong(s, start, start + len, 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 new NumberFormatException("");
}
}
内容字符串化
//最简单的形式
public String toString() {
return toString(value);
}
//静态方法 将将整型转化为字符串
@HotSpotIntrinsicCandidate
public static String toString(int i) {
// 统计整数i中包含的符号数量(包括负号),即计算整数i转为字符串后的长度
int size = stringSize(i);
if(COMPACT_STRINGS) {
byte[] buf = new byte[size];
getChars(i, size, buf);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[size * 2];
StringUTF16.getChars(i, size, buf);
return new String(buf, UTF16);
}
}
// 静态方法将将整型转化为字符串 返回整型值i的radix形式
public static String toString(int i, int radix) {
if(radixCharacter.MAX_RADIX)
radix = 10;
/* Use the faster version */
if(radix == 10) {
return toString(i);
}
if(COMPACT_STRINGS) {
byte[] buf = new byte[33];
boolean negative = (i<0);
int charPos = 32;
if(!negative) {
i = -i;
}
while(i<=-radix) {
buf[charPos--] = (byte) digits[-(i % radix)];
i = i / radix;
}
buf[charPos] = (byte) digits[-i];
if(negative) {
buf[--charPos] = '-';
}
return StringLatin1.newString(buf, charPos, (33 - charPos));
}
return toStringUTF16(i, radix);
}
// 静态方法将将整型转化为字符串 返回整型值i的二进制形式
public static String toBinaryString(int i) {
return toUnsignedString0(i, 1);
}
// 静态方法将将整型转化为字符串 返回整型值i的八进制形式
public static String toOctalString(int i) {
return toUnsignedString0(i, 3);
}
// 静态方法将将整型转化为字符串 返回整型值i的十六进制形式
public static String toHexString(int i) {
return toUnsignedString0(i, 4);
}
// 静态方法将将整型转化为字符串 返回当前int的无符号形式的值的
public static String toUnsignedString(int i) {
return Long.toString(toUnsignedLong(i));
}
// 静态方法将将整型转化为字符串 返回当前int的无符号形式的值的radix进制形式
public static String toUnsignedString(int i, int radix) {
return Long.toUnsignedString(toUnsignedLong(i), radix);
}
/**
* Convert the integer to an unsigned number.
*/
// 返回整型值val的2^shift进制形式
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);
if(COMPACT_STRINGS) {
byte[] buf = new byte[chars];
formatUnsignedInt(val, shift, buf, 0, chars);
return new String(buf, LATIN1);
} else {
byte[] buf = new byte[chars * 2];
formatUnsignedIntUTF16(val, shift, buf, 0, chars);
return new String(buf, UTF16);
}
}
// 返回整型值i的radix形式,UTF16版本
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));
}
/*
* 从buf的offset索引处开始,存入变量val在2^shift进制下的后len位
* shift取1、3、4时分别代表二进制、八进制、16进制
* 如果len的长度超过该进制下的有效数位长度,则前面空白部分补0
*
* 举例:
* 十进制数12345的八进制形式为30071
*
* char[] buf = new char[10];
*
* formatUnsignedInt(12345, 3, buf, 0, 5) // buf={'3','0','0','7','1','\0','\0','\0','\0','\0'}
* formatUnsignedInt(12345, 3, buf, 0, 7) // buf={'0','0','3','0','0','7','1','\0','\0','\0'}
* formatUnsignedInt(12345, 3, buf, 2, 7) // buf={'\0','\0','0','0','3','0','0','7','1','\0'}
*/
static void formatUnsignedInt(int val, int shift, char[] buf, int offset, int len) {
// assert shift > 0 && shift <=5 : "Illegal shift value";
// assert offset >= 0 && offset < buf.length : "illegal offset";
// assert len > 0 && (offset + len) <= buf.length : "illegal length";
int charPos = offset + len;
int radix = 1 << shift;
int mask = radix - 1;
// 循环len次
do {
buf[--charPos] = Integer.digits[val & mask];
val >>>= shift;
} while(charPos>offset);
}
/** byte[]/LATIN1 version */
// formatUnsignedInt方法的byte[]/LATIN1版本,将数字0到9分别存储为对应的ANSI码,'\0'存储为数字0
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 */
// formatUnsignedInt方法的byte[]/UTF16版本,每个char存为两个byte
private 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);
}
/*
* 统计整数i中包含的符号数量(包括负号),为转为字符串做准备
* 比如stringSize(12345)返回5,stringSize(-12345)返回6
*/
//静态方法 统计整数i中包含的符号数量 可以用于整数位数获取
static int stringSize(int x) {
int d = 1;
if(x >= 0) {
d = 0;
x = -x;
}
int p = -10;
for(int i = 1; i<10; i++) {
if(x>p)
return i + d;
p = 10 * p;
}
return 10 + d;
}
// 将整数i中包含的符号转为byte存入buf
static int getChars(int i, int index, byte[] buf) {
int q, r;
int charPos = index;
boolean negative = i<0;
if(!negative) {
i = -i;
}
// Generate two digits per iteration
while(i<=-100) {
q = i / 100;
r = (q * 100) - i;
i = q;
buf[--charPos] = DigitOnes[r];
buf[--charPos] = DigitTens[r];
}
// We know there are at most two digits left at this point.
q = i / 10;
r = (q * 10) - i;
buf[--charPos] = (byte) ('0' + r);
// Whatever left is the remaining digit.
if(q<0) {
buf[--charPos] = (byte) ('0' - q);
}
if(negative) {
buf[--charPos] = (byte) '-';
}
return charPos;
}
无符号化
// 将当前int转换为无符号形式,用long存储
public static long toUnsignedLong(int x) {
return ((long) x) & 0xffffffffL;
}
比较
这里实现了Comparable接口的compareTo方法
// 比较两个int(按自然顺序比较)
public static int compare(int x, int y) {
return (x
}
// 比较两个Integer(按自然顺序比较)
public int compareTo(Integer anotherInteger) {
return compare(this.value, anotherInteger.value);
}
// 以无符号形式比较两个int(按自然顺序比较)
public static int compareUnsigned(int x, int y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
通过 x.compareTo(y) 来“比较x和y的大小
返回“负数”,意味着“x
返回“零”,意味着“x==y”
返回“正数”,意味着“x>y”
位操作
// 返回二进制位中值为1的bit位的数量(把int值i表示为二进制形式)
@HotSpotIntrinsicCandidate
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;
}
// 将i中的bit循环左移distance位
public static int rotateLeft(int i, int distance) {
return (i << distance) | (i >>> -distance);
}
// 将i中的bit循环右移distance位
public static int rotateRight(int i, int distance) {
return (i >>> distance) | (i << -distance);
}
// 以bit为单位逆置bit顺序
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;
return reverseBytes(i);
}
// 以字节为单位逆置字节顺序
@HotSpotIntrinsicCandidate
public static int reverseBytes(int i) {
return (i << 24) | ((i & 0xff00) << 8) | ((i >>> 8) & 0xff00) | (i >>> 24);
}
// 判断i的正负。遇到负数返回-1,正数返回1,0返回0。
public static int signum(int i) {
// HD, Section 2-7
return (i >> 31) | (-i >>> 31);
}
// 返回二进制位中开头连续的0的个数(把int值i表示为二进制形式)
@HotSpotIntrinsicCandidate
public static int numberOfLeadingZeros(int i) {
// HD, Count leading 0's
if(i<=0)
return i == 0 ? 32 : 0;
int n = 31;
if(i >= 1 << 16) {
n -= 16;
i >>>= 16;
}
if(i >= 1 << 8) {
n -= 8;
i >>>= 8;
}
if(i >= 1 << 4) {
n -= 4;
i >>>= 4;
}
if(i >= 1 << 2) {
n -= 2;
i >>>= 2;
}
return n - (i >>> 1);
}
// 返回二进制位中末尾连续的0的个数(把int值i表示为二进制形式)
@HotSpotIntrinsicCandidate
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);
}
// 返回二进制位中开头首次出现的1所占的数位,比如00110100,返回32
public static int highestOneBit(int i) {
return i & (MIN_VALUE >>> numberOfLeadingZeros(i));
}
// 返回二进制位中末尾最后出现的1所占的数位,比如00110100,返回4
public static int lowestOneBit(int i) {
// HD, Section 2-1
return i & -i;
}
简单运算
// 求和
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);
}
// 除法运算,计算结果转为int后返回。计算前需要先将两个int值转换为无符号形式,并用long存储。
public static int divideUnsigned(int dividend, int divisor) {
// In lieu of tricky code, for now just use long arithmetic.
return (int) (toUnsignedLong(dividend) / toUnsignedLong(divisor));
}
// 取余运算,计算结果转为int后返回。计算前需要先将两个int值转换为无符号形式,并用long存储。
public static int remainderUnsigned(int dividend, int divisor) {
// In lieu of tricky code, for now just use long arithmetic.
return (int) (toUnsignedLong(dividend) % toUnsignedLong(divisor));
}
剩余代码
剩下的这三个方法 都是继承自Object 没什么好说的了
@Override
public int hashCode() {
return Integer.hashCode(value);
}
public static int hashCode(int value) {
return value;
}
public boolean equals(Object obj) {
if(obj instanceof Integer) {
return value == ((Integer) obj).intValue();
}
return false;
}
自动装箱与自动拆箱
其实自动装箱与拆箱更像是一种障眼法,是编译器帮我们做了一些事情
比如说自动装箱
Integer i = 1;
编译器在编译的时候自动作以下的语法编译:Integer i = Integer.valueOf(1);
自动拆箱,也就是将对象中的基本数据从对象中自动取出。
Integer i = 1; //装箱
int t = i; //拆箱
类似于自动装箱 实际上语法编译为: int t = i.intValue();
关于Integer的自动装箱
// 在-128~127 之内的数
Integer i1 =100;
Integer i2 =100;
System.out.println("i1==i2: "+(i1==i2));
//在-128~127 之外的数
Integer i3 =200;
Integer i4 =200;
System.out.println("i3==i4: "+(i3==i4));
输出的结果是
输出的结果是:
i1==i2: true
i3==i4: false
equals() 比较的是两个对象的值(内容)是否相同。
"==" 比较的是两个对象的引用(内存地址)是否相同,也用来比较两个基本数据类型的变量值是否相等。
结合一下前面的Integer.valueOf(int i)源代码
很容易理解
对于–128到127(默认是127)之间的值,Integer.valueOf(int i) 返回的是缓存的Integer对象(并不是新建对象)
所以范例中,i3 与 i4实际上是指向同一个对象。
而其他值,执行Integer.valueOf(int i) 返回的是一个新建的 Integer对象,所以范例中,i1与i2 指向的是不同的对象。
为什么要说这个问题呢?之前见过一道类似的面试题,当初怎么想也想不明白,如今看过源码之后,茅塞顿开。