zoukankan      html  css  js  c++  java
  • JDK源码分析 – Integer

    Integer类的申明

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

    Integer用于对int类型数值的封装,并提供一些int类型数据操作的方法,Integer继承自Number类,Number是JDK的一个代表数值的超类,提供一些用于不同数值之间类型转换方法,常见的数值类型Double、Float等都继承自Number

    Integer还实现了Comparable接口,主要用于Integer对象之间比较。

    Integer字段、属性说明

    Integer是对int型数值的封装,int型,占4个字节(JDK中定义占4字节),每个字节8位因次是32位,再除去一个符号位,因此范围是-2^31~2^31-1

    下面列举几个重要的字段解释一下:

        /**
         *代表Integer封装的int整形数值 
         */
        private final int value;
        
        /**
         *限制Integer对象存放最小值 -2^31
         */
        @Native public static final int   MIN_VALUE = 0x80000000;
    
        /**
         * //限制Integer对象存放最大值 2^31-1
         */
        @Native public static final int   MAX_VALUE = 0x7fffffff;
    
    
        /**
         *表示int二进制补码形式的值的位数。
         */
        @Native public static final int SIZE = 32;
    
        /**
         * 用于以int二进制补码形式表示值的字节数32/8 = 4字节
         */
        public static final int BYTES = SIZE / Byte.SIZE;

    Integer 部分方法分析

    Integer类内部提供了很多方法,用于数值转换等操作,下面仍然是列举几个经常用到的分析一下实现过程:

    构造函数Integer(String s)

    /**
     * 构造函数,允许传入一个字符串,通过内部函数parseInt尝试将其转成10进制int型数值,默认转成10进制,如果传入的String无法转换成Int则跑出异常
     */
    public Integer(String s) throws NumberFormatException {
            this.value = parseInt(s, 10);
    }

    int parseInt(String s, int radix)方法

    将字符串参数解析为指定的几进制带符号整数,转换失败抛出异常,string参数:将要转换为数值的字符串,int参数:代表需要转换的是几进制数值

    JDK源码注释中给出一些示例:

        /**
         * JDK源码注释中的示例: 
         * <p>Examples:
         * <blockquote><pre>
         * parseInt("0", 10) returns 0
         * parseInt("473", 10) returns 473
         * parseInt("+42", 10) returns 42
         * parseInt("-0", 10) returns 0
         * parseInt("-FF", 16) returns -255
         * parseInt("1100110", 2) returns 102
         * parseInt("2147483647", 10) returns 2147483647
         * parseInt("-2147483648", 10) returns -2147483648
         * parseInt("2147483648", 10) throws a NumberFormatException
         * parseInt("99", 8) throws a NumberFormatException
         * parseInt("Kona", 10) throws a NumberFormatException
         * parseInt("Kona", 27) returns 411787
         */
        public static int parseInt(String s, int radix)
                    throws NumberFormatException
        {
            /*
             * WARNING: This method may be invoked early during VM initialization
             * before IntegerCache is initialized. Care must be taken to not use
             * the valueOf method.
             */

    //字符串为空直接异常 if (s == null) { throw new NumberFormatException("null"); } //判断radix合法性,Integer内部允许2进制-36进制之间转换 //为什么是36进制? 看个示例 // Integer.parseInt("A", 16) = 10     // Integer.parseInt("a", 16) =10     // 上面可以看出不区分大小写,是不是10个数字+26个母? 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; //符号,正数or负数 int i = 0, len = s.length(); int limit = -Integer.MAX_VALUE; int multmin; int digit; //字符串长度大于0 if (len > 0) { char firstChar = s.charAt(0); if (firstChar < '0') { // Possible leading "+" or "-" 判断第一个字符是不是符号为=位 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); //长度是1,只有符号位,没有数值,抛异常 i++; } multmin = limit / radix; //遍历字符转,从最高位开始,整个过程以负数计算,逐位乘以单位制,最后再修正符号位,以10进制数123为例。转换过程如下 // result = -1 // result = -1*10-2 = -12 // result = -12*10-3 = -123 while (i < len) { // Accumulating negatively avoids surprises near MAX_VALUE digit = Character.digit(s.charAt(i++),radix); //将字符转换为radix进制数值,比如Character.digit(‘c’,16) = 12 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; //修正符号位 }

    其他parseInt相关方法也都是调用这个最基础的方法进行转换。

    Integer valueOf(int i)方法

    返回指定int值的Integer实例,如果Integer不需要新实例,可优先使用此方法,而不是构造函数,因为此方法会缓存经常请求的值的Integer实例。该方法将始终缓存-128至127(含)范围内的值,并可缓存此范围之外的其他值

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

     Valueof方法内部使用了IntegerCache,判断如果数值在[IntegerCache.low, IntegerCache.high]这个范围内,则从缓存中读取,否则调用构造函数创建一个Integer实例

    private static class IntegerCache {
            static final int low = -128; //最小值 -128
            static final int high;       //最大值
            static final Integer cache[];
    
    //静态代码块,在Integer类加载时就已经缓存好
            static {
                // high value may be configured by property
                int h = 127;  //最大值 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);               //在配置参数和默认h中取最大值
                        // 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++); //缓存integer对象
    
                // range [-128, 127] must be interned (JLS7 5.1.7)
                assert IntegerCache.high >= 127;  
            }
    
            private IntegerCache() {}
        }

    Valueof()方法完成将int型转换成Integer对象,其实就是一个装箱操作,Integer类型也可以直接赋值一个int数值:Integer integer = 100 这其实就是通过调用valueof()方法完成的。

    相对应的方法:int intValue() 获取Integer对象内部value值,其实就是完成一个拆箱操作

    public int intValue() {
            return value;
        }

    下面给出一组测试示例,通过对Integer对比分析一下Integer对象的装箱拆箱和IntegerCache缓存:

            Integer integer0 = Integer.valueOf(1);   //IntegerCache缓存中读取
            Integer integer1 = new Integer(1);        //创建新实例
            Integer integer2 = new Integer(1);        //创建新实例
            System.out.println(integer1.equals(integer2)); //true Integer.equal内部实现并不是比较两个Integer对象的引用,而是比较Integer.value值是否相等
    System.out.println(integer1==integer2); //false integer1和integer2是两个不同的对象,引用不一样 Integer integer3 = 1; Integer integer4 = 1; System.out.println(integer3 == integer4);//true,integer3和integer4都完成装箱,从IntegerCache中取出相同的实例 Integer integer8 = 128; Integer integer9 = 128; System.out.println(integer8 == integer9);//false,integer8和integer9都完成装箱,New Integer(128)==new Integer(128) System.out.println(integer3 == integer1);//false,integer3通过调用valueof做了装箱操作 实际相当于 Integer.valueOf(1)==integer1 System.out.println(integer3 == integer0);//true,integer3通过调用valueof做了装箱操作 实际相当于 Integer.valueOf(1)==integer0 ,都从IntegerCache缓存中读取 int integer5 = 1; Integer integer6 = new Integer(1); System.out.println(integer5 == integer5);//true 当Integer对象和int比较时,Integer对象调用intValue完成自动拆箱,转换为int,相当于两个int型比较 Integer integer7 = 1; System.out.println(integer7==integer5); //true integer7先装箱,比较时又做了拆箱操作

    Integer和int的区别

             Integer是对int型封装后的类,int是java的一种基本数据类型(byte,char,short,int,long,float,double,boolean)

        Integer是对象的引用,默认值为null,实例化后是一个对象的引用,指向存放该对象的地址,int作为基本数据类型,默认值为0

    
    
  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/ashleyboy/p/9043674.html
Copyright © 2011-2022 走看看