1.値の範囲と基本的なデータタイプの
ソースコード
public final class Integer extends Number implements Comparable<Integer> {
//该值用于定义Integer取值的最小值
@Native public static final int MIN_VALUE = 0x80000000;
//该值用于定义Integer取值的最大值
@Native public static final int MAX_VALUE = 0x7fffffff;
//该值用于定义Integer的基本数据类型
@SuppressWarnings("unchecked")
public static final Class<Integer> TYPE = (Class<Integer>) Class.getPrimitiveClass("int");
}
ソースコード分析
- Integerは、finalによって変更されたタイプであり、Numberクラスを継承し、Comparableインターフェイスを実装します。
- 整数の最小値は-2 ^ 31で、最大値は2 ^ 31-1です。
- Integerの基本的なデータタイプはintです。
2.toString
ソースコード
public final class Integer extends Number implements Comparable<Integer> {
public static String toString(int i) {
if (i == Integer.MIN_VALUE)
return "-2147483648";
//计算整数i的位数
int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i);
char[] buf = new char[size];
/**
* 将代表整数i的字符放入字符数组buf
* 字符从指定索引处的最低有效数字(不包括最高位字符)开始向后放置
*/
getChars(i, size, buf);
return new String(buf, true);
}
final static int [] sizeTable = {
9,99,999,9999,99999,999999,9999999,99999999,999999999,Integer.MAX_VALUE};
static int stringSize(int x) {
for (int i = 0; ; i++)
if (x <= sizeTable[i])
return i + 1;
}
}
ソースコード分析
整数値の長さを計算するときは、1次元配列を作成してから、整数値を配列の各値と比較します。ただし、長さの計算には、よく使われる除算法を使用していません。これは、コンピュータが加算、減算、乗算よりも除算の計算効率が低いためです。除算を避けて計算効率を上げるために、この方法を採用しています。
まとめ
特定の数値の長さを計算するときは、IntegerクラスのstringSize()メソッドを参照できます。
3.IntegerCache
ソースコード
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
int h = 127;
//缓存的最大值是VM参数里java.lang.Integer.IntegerCache.high这个属性
String integerCacheHighPropValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
//最大数组大小为Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) - 1);
} catch (NumberFormatException nfe) {
//如果无法将属性解析为int,则忽略它
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for (int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
assert Integer.IntegerCache.high >= 127;
}
private IntegerCache() {
}
}
ソースコード分析
- Integerを初期化した後、IntegerCacheは[-128,127]の間のデータをキャッシュします。この間隔の上限は構成可能であり、属性java.lang.Integer.IntegerCache.highに依存します。この属性はVMで使用できます-XX:AutoBoxCacheMax = 2000または、調整のために-Djava.lang.Integer.IntegerCache.high = 2000。
- この範囲のデータがより一般的に使用されます。キャッシュを追加するとパフォーマンスが向上し、毎回新しいキャッシュを作成する必要がないため、システムリソースが無駄になります。同時に、IntegerのhashCodeメソッドによれば、IntegerのhashCodeが独自のint値を返すことがわかります。
インタビューポイント
//程序1-2
public class App {
public static void main(String[] args) {
Integer a = 1;
Integer b = 1;
Integer c = new Integer(1);
Integer d = 1000;
Integer e = 1000;
System.out.println(a == b);//true
System.out.println(b == c);//false
System.out.println(d == e);//false
}
}
4.valueOfおよびparseInt
ソースコード
public final class Integer extends Number implements Comparable<Integer> {
public static Integer valueOf(int i) {
if (i >= Integer.IntegerCache.low && i <= Integer.IntegerCache.high)
return Integer.IntegerCache.cache[i + (-Integer.IntegerCache.low)];
return new Integer(i);
}
public static int parseInt(String s) throws NumberFormatException {
return parseInt(s,10);
}
public static int parseInt(String s, int radix) throws NumberFormatException {
if (s == null) {
throw new NumberFormatException("null");
}
if (radix < Character.MIN_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");
}
int result = 0;
boolean negative = false;
int i = 0, len = s.length();
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
if (len > 0) {
char firstChar = s.charAt(0);
if (firstChar < '0') {
if (firstChar == '-') {
negative = true;
limit = Integer.MIN_VALUE;
} else if (firstChar != '+')
throw NumberFormatException.forInputString(s);
if (len == 1)
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
while (i < len) {
digit = Character.digit(s.charAt(i++), radix);
if (digit < 0) {
throw NumberFormatException.forInputString(s);
}
if (result < multmin) {
throw NumberFormatException.forInputString(s);
}
result *= radix;
if (result < limit + digit) {
throw NumberFormatException.forInputString(s);
}
result -= digit;
}
} else {
throw NumberFormatException.forInputString(s);
}
return negative ? result : -result;
}
}
ソースコード分析
- valueOfメソッドは、キャッシュから値をフェッチします。キャッシュにヒットすると、リソースのオーバーヘッドが削減されます。
- parseIntメソッドは、最初に例外処理を実行し、次に着信文字列に符号があるかどうかを判別します。ビット数をインターセプトした後、乗算と減算を使用してint値を取得し、最後に符号を判別して結果を返します。