Integer源码阅读

淡淡的烟草味﹌ 2022-02-19 19:13 485阅读 0赞

Integer源码分析

一道面试题

  1. /** * @author xuelongjiang */
  2. public class Test6 {
  3. public static void main(String[] args) {
  4. Integer var0 = 100;
  5. Integer var1 = 100;
  6. Integer var2 = 130;
  7. Integer var3 = 130;
  8. System.out.println(var0 == var1);
  9. System.out.println(var2 == var3);
  10. }
  11. }

输出结果是什么呢?

第一种:

  1. true
  2. true

第二种:

  1. false
  2. false

其实上面的输出都不对,正确输出是:

  1. true
  2. false

那么为什么会是这种输出结果呢?

我们知道 Integer var0 = 100
这里java编译器自动帮我们把原始类型装箱Integer类型。来看一下过编译后的代码我们反编译下上面的语句实际执行的是什么。

  1. public static void main(java.lang.String[]);
  2. Code:
  3. 0: bipush 100
  4. 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  5. 5: astore_1
  6. 6: bipush 100
  7. 8: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  8. 11: astore_2
  9. 12: sipush 130
  10. 15: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  11. 18: astore_3
  12. 19: sipush 130
  13. 22: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  14. 25: astore 4
  15. 27: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
  16. 30: aload_1
  17. 31: aload_2

可以看到

  1. 0: bipush 100
  2. 2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
  3. 5: astore_1

表明了实际上

Integer var0 = 100;调用的是

Integer var0 = Integer.valueOf(100);这个方法.

在后面,我们分析一下*Integer.valueOf()*这个方法的原理。

类定义

Integer提供了与string,int,long,short,float,double类型转换的方法,以及一些简单的大小比较.

  1. public final class Integer extends Number implements Com
  2. parable<Integer>

final表示Integer是不可变对象(不可变对象是线程安全的), 继承Number类(number类实现了Serializable表示可以被序列化),实现Comparable接口(对象可以比较大小)。

构造器

1.

  1. public Integer(int value) {
  2. this.value = value;
  3. }

初始化Integer的值大小。

2.

  1. public Integer(String s) throws NumberFormatException {
  2. this.value = parseInt(s, 10);
  3. }

使用string类型类构造integer

属性

1.

  1. public static final int MIN_VALUE = 0x80000000;

Integer最小的值大小-2^31次方

2.

  1. public static final int MAX_VALUE = 0x7fffffff;

Integer最大的值大小2^31次方

3.

  1. private final int value;

包装类存储的整形值。

内部类

在Integer加载过程初始化IntegerCache,默认最大值是127,最小值-128,并且会出实话**cache[]**数组来存储 -128 ~ 127。在valueOf方法中如果在这个返回内,直接从缓存取值,这也是上面的面试题返回true false 的根本原因。

  1. private static class IntegerCache {
  2. static final int low = -128;
  3. static final int high;
  4. static final Integer cache[];
  5. static {
  6. // high value may be configured by property
  7. int h = 127;
  8. String integerCacheHighPropValue =
  9. sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
  10. if (integerCacheHighPropValue != null) {
  11. try {
  12. int i = parseInt(integerCacheHighPropValue);
  13. i = Math.max(i, 127);
  14. // Maximum array size is Integer.MAX_VALUE
  15. h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
  16. } catch( NumberFormatException nfe) {
  17. // If the property cannot be parsed into an int, ignore it.
  18. }
  19. }
  20. high = h;
  21. cache = new Integer[(high - low) + 1];
  22. int j = low;
  23. for(int k = 0; k < cache.length; k++)
  24. cache[k] = new Integer(j++);
  25. // range [-128, 127] must be interned (JLS7 5.1.7)
  26. assert IntegerCache.high >= 127;
  27. }
  28. private IntegerCache() { }
  29. }

类方法

1.

整形值转为16进制,相应的还有转为8进制,2进制方法。

  1. public static String toHexString(int i) {
  2. return toUnsignedString0(i, 4);
  3. }

2.

开篇说到的Integer var0 = 100 实际上调用的是这个方法,我们已经在IntegerCache解释了会从缓存中取值。

  1. public static Integer valueOf(int i) {
  2. if (i >= IntegerCache.low && i <= IntegerCache.high)
  3. return IntegerCache.cache[i + (-IntegerCache.low)];
  4. return new Integer(i);
  5. }

##实例方法

1.

  1. public Integer(String s) throws NumberFormatException {
  2. this.value = parseInt(s, 10);
  3. }

2.

字符串转为10进制数字,

radix不能小于2,不能大于36.

while循环中有一个判断 result < multmin的实际意思不能大于MAX_VALUE 与不能小于MIN_VALUE

**result *= radix;**的意思每次循环到这里扩大十倍最终会把每一位放到响应的位置。result -= digit 当前个位数的值。

  1. public static int parseInt(String s, int radix)
  2. throws NumberFormatException
  3. {
  4. /* * WARNING: This method may be invoked early during VM initialization * before IntegerCache is initialized. Care must be taken to not use * the valueOf method. */
  5. if (s == null) {
  6. throw new NumberFormatException("null");
  7. }
  8. if (radix < Character.MIN_RADIX) {
  9. throw new NumberFormatException("radix " + radix +
  10. " less than Character.MIN_RADIX");
  11. }
  12. if (radix > Character.MAX_RADIX) {
  13. throw new NumberFormatException("radix " + radix +
  14. " greater than Character.MAX_RADIX");
  15. }
  16. int result = 0;
  17. boolean negative = false;
  18. int i = 0, len = s.length();
  19. int limit = -Integer.MAX_VALUE;
  20. int multmin;
  21. int digit;
  22. if (len > 0) {
  23. char firstChar = s.charAt(0);
  24. if (firstChar < '0') { // Possible leading "+" or "-"
  25. if (firstChar == '-') {
  26. negative = true;
  27. limit = Integer.MIN_VALUE;
  28. } else if (firstChar != '+')
  29. throw NumberFormatException.forInputString(s);
  30. if (len == 1) // Cannot have lone "+" or "-"
  31. throw NumberFormatException.forInputString(s);
  32. i++;
  33. }
  34. multmin = limit / radix;
  35. while (i < len) {
  36. // Accumulating negatively avoids surprises near MAX_VALUE
  37. digit = Character.digit(s.charAt(i++),radix);
  38. if (digit < 0) {
  39. throw NumberFormatException.forInputString(s);
  40. }
  41. if (result < multmin) {
  42. throw NumberFormatException.forInputString(s);
  43. }
  44. result *= radix;
  45. if (result < limit + digit) {
  46. throw NumberFormatException.forInputString(s);
  47. }
  48. result -= digit;
  49. }
  50. } else {
  51. throw NumberFormatException.forInputString(s);
  52. }
  53. return negative ? result : -result;
  54. }

3.

继承自Number方法,强转为byte

  1. public byte byteValue() {
  2. return (byte)value;
  3. }

4.

继承自Number方法,返回属性 value的值。

  1. public int intValue() {
  2. return value;
  3. }

5.

继承自Number方法,强转为long

  1. public long longValue() {
  2. return (long)value;
  3. }

equals() && hashCode()

使用属性value作为hashCode

  1. public int hashCode() {
  2. return Integer.hashCode(value);
  3. }
  4. public static int hashCode(int value) {
  5. return value;
  6. }

重写了Object的equals方法
判断是否是integer是的话比较value属性是否相等。

  1. public boolean equals(Object obj) {
  2. if (obj instanceof Integer) {
  3. return value == ((Integer)obj).intValue();
  4. }
  5. return false;
  6. }

发表评论

表情:
评论列表 (有 0 条评论,485人围观)

还没有评论,来说两句吧...

相关阅读