七的博客

Integer浅析-JDK1.8

源码分析

java.lang.Integer浅析

源码分析环境

  • OS: Ubuntu 16.04 LTS X64
  • IDE: IDEA 2017.1.3
  • JDK:
    • HotSpot™ 64-Bit JDK1.6
    • HotSpot™ 64-Bit JDK1.7
    • HotSpot™ 64-Bit JDK1.8
    • OpenJDK 64-Bit Server VM (build 25.131-b11, mixed mode) OpenJDK1.8

一. Integer类的声明

public final class Integer extends Number implements Comparable<Integer>{}

Integer

  • Integer是一个 final 类,也就是不可变的类。
  • 继承了 Number 这个抽象类,拥有了父类的一系列方法,同时也隐式的实现了 Serializable 接口。
  • 实现了 Comparable 接口,说明它是可以进行比较的,可以与其他Integer对象进行比较。 使用泛型确保了compareTo方法的类型安全。

二. 特殊的内部类

Java 自动缓存 - 128 到 127 之间的整数,这个缓存将会在第一次使用时被初始化,缓存的大小受 JVM 运行参数 -XX:AutoBoxCacheMax=<size>控制,可以通过这个进行更改。

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() {}
    }
    

直接上例子,默认情况下是这样的:

        Integer integer1 = 127;
        Integer integer2 = 127;
        System.out.println(integer1 == integer2);     // true 

        Integer integer3 = 128;
        Integer integer4 = 128;
        System.out.println(integer3 == integer4);     // false 

        Integer integer5 = -128;
        Integer integer6 = -128;
        System.out.println(integer5 == integer6);     // true 

        Integer integer7 = -129;
        Integer integer8 = -129;
        System.out.println(integer7 == integer8);          // flase 

然后如果我们还想让它缓存更大的数的话就给 JVM 设置一个运行参数,这里假如我设置到最大缓存到 256 ,-XX:AutoBoxCacheMax= 256

        Integer integer1 = 256;
        Integer integer2 = 256;
        System.out.println(integer1 == integer2);     // true

        Integer integer3 = 257;
        Integer integer4 = 257;
        System.out.println(integer3 == integer4);      // false 超过了最大缓存就比较地址了,没有缓存可以取了

三. Integer的属性

最小值

最小值是 2^-31 ,换算过来就是 - 2147483648 ,因为是个静态属性,可以直接通过 Integer.MIN_VALUE 取到

    //  A constant holding the minimum value an {@code int} can have, -2^31
    @Native public static final int   MIN_VALUE = 0x80000000;

最大值

最大值是2^31,换算过来就是2147483647,因为是个静态属性,可以直接通过Integer.MAX_VALUE取到。

    // A constant holding the maximum value an  int can have, 2^31-1.
   @Native public static final int   MAX_VALUE = 0x7fffffff;

类型

根据方法注释我们可以知道是 Integer 类型的 Type 是一个基本类型。

 /**
     * The  Class instance representing the primitive type int.
     * @since   JDK1.1
     */
    @SuppressWarnings("unchecked")
    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int");

然后我们这里就会引发一个疑问了,为什么 Integer 的 Type 会是 in.class 呢?,这里我们其实可以像个例子:

        System.out.println(Integer.TYPE);                        //  int 
        // 使用 == 进行比较
        System.out.println(Integer.TYPE == int.class);          // true
        System.out.println(Integer.class == int.class);         // false
        // 如果还想更加准确地比较,可以使用System.identityHashCode()产生一个哈希码,这个是给予地址生成的,不是给予内容
        System.out.println(System.identityHashCode(Integer.TYPE));      //  2061475679
        System.out.println(System.identityHashCode(int.class));        //  2061475679
        System.out.println(System.identityHashCode(Integer.class));    //   410424423

这里我们可以很清楚的得到理论就是:
- Integer.TYPE 跟 int.class 是相等的,因为 Integer.TYPE 这个常量就是通过 Class.getPrimitiveClass(”int”) 得到的。 - Integer.class 跟 int.class 是不相等的,因为 Integer.class 是个包装类,我们可以看到它的源码, int.class 的源码不能直接在 JDK 中看到。

列举出所有可能作为数字的字母

列举出所有可能作为数字的字母,每个字母对应着 ASCII 码,是可以进行转换的,给方法内部使用的。

     //  All possible chars for representing a number as a String
    final static 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'
    };

四. 构造方法

  • 传入一个 int 类型的值
public Integer(int value) {
        this.value = value;
    }
  • 传入一个 String 类型的数字
public Integer(String s) throws NumberFormatException {
        this.value = parseInt(s, 10);
    }

五.Integer的方法

toString

重写了 Object 的 toString() 方法。

public static String toString(int i, int radix) {
        if (radix < Character.MIN_RADIX || radix > Character.MAX_RADIX)
            radix = 10;

        /* Use the faster version */
        if (radix == 10) {
            return toString(i);
        }

        char buf[] = new char[33];
        boolean negative = (i < 0);
        int charPos = 32;

        if (!negative) {
            i = -i;
        }

        while (i <= -radix) {
            buf[charPos--] = digits[-(i % radix)];
            i = i / radix;
        }
        buf[charPos] = digits[-i];

        if (negative) {
            buf[--charPos] = '-';
        }

        return new String(buf, charPos, (33 - charPos));
    }

toUnsignedString

转变成一个无符号的 String 类型。

 public static String toUnsignedString(int i, int radix) {
        return Long.toUnsignedString(toUnsignedLong(i), radix);
    }

valueOf

  • 传入一个文本型的数字转为 Integer 类型。
public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
  • 手动装箱,把一个基本数据类型转为包装类型
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

转换为基本数据类型

 public byte byteValue();
 public short shortValue();
 public int intValue();
 public long longValue();
 public float floatValue();
 public double doubleValue();

equals

首先不是 Integer 类型就直接不相等,否则直接比对值。

public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }

String 转 Integer

Integer getInteger(String nm);
Integer getInteger(String nm, int val);
Integer getInteger(String nm, Integer val);
Integer decode(String nm);
Integer valueOf(String s);
Integer valueOf(String s, int radix);
````






### String 转基本类型

```java
int parseUnsignedInt(String s);
int parseUnsignedInt(String s, int radix);
int parseInt(String s);
int parseInt(String s, int radix);

compareTo

跟另外一个 Integer 类型比较。

public int compareTo(Integer anotherInteger) {
        return compare(this.value, anotherInteger.value);
    }

六.静态方法

compare

  • 传入两个 int 类型的数字进行比较
public static int compare(int x, int y) {
        return (x < y) ? -1 : ((x == y) ? 0 : 1);
    }
  • 传入两个无符号类型的数字进行比较
 public static int compareUnsigned(int x, int y) {
        return compare(x + MIN_VALUE, y + MIN_VALUE);
    }

toUnsignedLong

转换为 Long 类型无符号

public static long toUnsignedLong(int x) {
        return ((long) x) & 0xffffffffL;
    }

sum

对两个数求和

public static int sum(int a, int b) {
        return a + b;
    }

max

比较 2 个数,并返回最大数(JDK1.8 )

 public static int max(int a, int b) {
        return Math.max(a, b);
    }

min

比较两个数,并返回最小的那个数(JDK1.8 )

public static int min(int a, int b) {
        return Math.min(a, b);
    }