文档章节

Integer类源码阅读(一)

夏夜流星
 夏夜流星
发布于 2013/12/29 20:57
字数 1547
阅读 1599
收藏 5
点赞 0
评论 0

一、类说明

    Integer类是用来包装原始类型int的类,用以表示原始类型int的面向对象的类。类中包含了原始类型int的值及相应的操作。

二、源码解析

package java.lang;
import java.util.Properties;
public final class Integer extends Number implements Comparable<Integer> {
    public static final int   MIN_VALUE = 0x80000000; //Integer中所能存储的最大值,即231-1。
    public static final int   MAX_VALUE = 0x7fffffff; //Integer中所能存储的最小值,即2-31。
    public static final Class<Integer>  TYPE = (Class<Integer>) Class.getPrimitiveClass("int"); //原始类型int的Class实例。
    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'     
    }; //所有可能的将数字表示为字符串的字符集合。
    //返回第二个参数所指定的进制数的第一个参数的字符串表示形式
    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));     
    }
    
    public static String toHexString(int i) {
        return toUnsignedString(i, 4);
    }
    
    public static String toOctalString(int i) {
        return toUnsignedString(i, 3);
    }
    
    public static String toBinaryString(int i) {
        return toUnsignedString(i, 1);
    }
    
    //转换int类型为无符号的字符串
    private static String toUnsignedString(int i, int shift) {
        char[] buf = new char[32];
        int charPos = 32;
        int radix = 1 << shift; //使用左移操作符,提升性能。
        int mask = radix - 1;
        do {
            buf[--charPos] = digits[i & mask]; //使用&位移操作符得出每一位上的数字。
            i >>>= shift; //移除已经得到的数字
        } while (i != 0);

        return new String(buf, charPos, (32 - charPos));
    }
    
    //十位数上的字符集
    final static char [] 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',
        } ;

    //个位数上的字符集
    final static char [] 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',
        } ;
   
    public static String toString(int i) {
        if (i == Integer.MIN_VALUE)
            return "-2147483648";
        int size = (i < 0) ? stringSize(-i) + 1 : stringSize(i); //如果i为负数,则字符串长度要加1。
        char[] buf = new char[size];
        getChars(i, size, buf); //获取i中字符的集合。
        return new String(buf, true);
    }
    
    static void getChars(int i, int index, char[] buf) {
        int q, r;
        int charPos = index;
        char sign = 0;

        if (i < 0) { //如果i为负数,则设置i的符号字符为'-'。
            sign = '-';
            i = -i;
        }

        // Generate two digits per iteration
        while (i >= 65536) { //如果i大于65536,则每一次都获取十位和个位上的数字对应的字符。
            q = i / 100;
        // really: r = i - (q * 100);
            r = i - ((q << 6) + (q << 5) + (q << 2)); //每次获得i的最后两位数
            i = q;
            buf [--charPos] = DigitOnes[r]; //存储r中在个位数集合中对应的字符
            buf [--charPos] = DigitTens[r]; //存储r中在十位数集合中对应的字符
        }

        // Fall thru to fast mode for smaller numbers
        // assert(i <= 65536, i);
        for (;;) { //i<65536的情况
            q = (i * 52429) >>> (16+3);
            r = i - ((q << 3) + (q << 1));  // r = i-(q*10) ... //每次获得i的最后两位数
            buf [--charPos] = digits [r];
            i = q;
            if (i == 0) break;
        }
        if (sign != 0) {
            buf [--charPos] = sign; //设置符号
        }
    }
    //定义sizeTable表示int中每个位数中最大的数,用于简便确定int数的长度。
    final static int [] sizeTable = { 9, 99, 999, 9999, 99999, 999999, 9999999,
                                      99999999, 999999999, Integer.MAX_VALUE };
    //使用上面的sizeTable定义来确定int数的字符串表示长度。           
    static int stringSize(int x) {
        for (int i=0; ; i++)
            if (x <= sizeTable[i])
                return i+1;
    }
    
    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(); //i表示当前遍历的s的位数
        int limit = -Integer.MAX_VALUE; //设置最小值为负的Integer的最大值
        int multmin;
        int digit;

        if (len > 0) { //如果字符串长度大于0,则进行转换
            char firstChar = s.charAt(0); //获取第一位字符
            //在第一位字符小于'0'的情况下,判定是否含有符号'+'、'-'
            if (firstChar < '0') { // Possible leading "+" or "-" 
                if (firstChar == '-') { //为负数的情况
                    negative = true;
                    limit = Integer.MIN_VALUE; //不能小于Integer的最小值
                } else if (firstChar != '+') //不为'-'时,如果不为'+',则表示符号错误。
                    throw NumberFormatException.forInputString(s);

                //如果字符串的长度等于1,且这个字符小于'0',则表示该字符串仅为一个符号,抛出异常
                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forInputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) { //进行进制的转换
                // Accumulating negatively avoids surprises near MAX_VALUE
                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; //根据符号返回正数还是负数
    }
    
    public static int parseInt(String s) throws NumberFormatException {
        return parseInt(s,10);
    }
    
    public static Integer valueOf(String s, int radix) throws NumberFormatException {
        return Integer.valueOf(parseInt(s,radix)); 
    }
    
    public static Integer valueOf(String s) throws NumberFormatException {
        return Integer.valueOf(parseInt(s, 10));
    }
    //内部字符缓存类
    private static class IntegerCache {
        //缓存的下界,-128,不可变  
        static final int low = -128;
        //缓存上界,暂为null
        static final int high;
        static final Integer cache[]; //利用数组来缓存

        static {
            // high value may be configured by property
            // 缓存上届,可以通过JVM属性来配置
            int h = 127;
            String integerCacheHighPropValue =
                sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            //获取
            if (integerCacheHighPropValue != null) {
                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);
            }
            high = h;

            //获取Integer中所有能保存的数据
            cache = new Integer[(high - low) + 1];
            int j = low;
            //缓存所有Integer的数据
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }
    
    public static Integer valueOf(int i) {
        assert IntegerCache.high >= 127; //断言Integer缓存中的上届必须大于或等于127
        if (i >= IntegerCache.low && i <= IntegerCache.high) //如果i在Integer缓存中,则直接取出
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i); //否则,直接创建一个实例
    }
}




© 著作权归作者所有

共有 人打赏支持
夏夜流星
粉丝 6
博文 4
码字总数 3844
作品 0
沙坪坝
程序员
java.lang包源码阅读之一:类目综述以及源码阅读第一个类Boolean

java.lang包下直属类,从Java Platform Standard Edition 7 Documentation中一查便知: 大体上按照上面的分类阅读,估计应该学别人的体例-------关键代码分析,加上编译通过可运行的用例。类...

treenewtreenew
2016/10/24
48
0
java.lang.Void 解析与使用

今天在查看源码的时候发现了 java.lang.Void 的类。这个有什么作用呢? 先通过源码查看下 从源码中发现该类是final的,不可继承,并且构造是私有的,也不能 new。 那么该类有什么作用呢? 下...

jijs
2017/12/15
0
0
从JDK源码看Writer

概况 Writer 是一个用于写字符流的抽象类,它将一些相通的写相关操作抽象到此类,方便各种写操作类的实现。一般来说子类只需要实现它的 write、flush 、close 等三个方法,但如果有需要还可以...

超人汪小建
2017/10/30
0
0
从JDK源码看InputStream

概况 JDK 给我们提供了很多实用的输入流 xxxInputStream,而 InputStream 是所有字节输入流的抽象。包括 ByteArrayInputStream 、FilterInputStream 、BufferedInputStream 、DataInputStre...

超人汪小建
2017/11/07
0
0
Java泛型——阅读

一. 泛型概念的提出(为什么需要泛型)? 首先,我们看下下面这段简短的代码: 1 public class GenericTest { public static void main(String[] args) { List list = new ArrayList(); list...

关河
2016/01/26
69
0
由自动装箱和拆箱引发我看Integer源码

背景和问题   在看别人整理的资料时,看到如下一段代码: package com.sitech.test;/** * 自动装箱和拆箱 jdk1.6 * @author liaowp /public class TestInteger { public static void main(...

张涛泽
2017/04/19
0
0
CSDN日报20170817——《如果不从事编程,我可以做什么?》

程序人生 | 如果不从事编程,我可以做什么? 作者:下一个丶奇迹 如果有一天不做编程了,我能做什么?或许,我会去开一家类似猫的天空之城一样的书店,天天在书香中度过,谈笑有鸿儒,往来无...

blogdevteam
2017/08/17
0
0
jdk源码阅读之 java.lang.Iterable

作用 Iterable 是一个接口, 子类只需要实现一个方法, 返回一个迭代器, 这个接口的主要作用就是:实现了这个接口的类的实例,能够使用循环进行遍历. 主要语义是为了表示一个对象可迭代. 使用 以...

0x0001
2016/12/12
15
0
Android应用性能优化之使用SparseArray替代HashMap

HashMap是java里比较常用的一个集合类,我比较习惯用来缓存一些处理后的结果。最近在做一个Android项目,在代码中定义这样一个变量,实例化时,Eclipse却给出了一个 performance 警告。 意 ...

Jerikc
2013/06/20
0
1
从JDK源码看关闭钩子

关闭钩子 Java提供了Shutdown Hook机制,它让我们在程序正常退出或者发生异常时能有机会做一些清场工作。使用的方法也很简单,即可。关闭钩子其实可以看成是一个已经初始化了的但还没启动的线...

超人汪小建
2017/10/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

TensorFlow 线性回归 拟合

用tf 对 一次函数进行拟合 效果 loss 简单实现如下 import tensorflow as tfimport numpy as npimport matplotlib.pyplot as plt# 保存显示数据plotdata = {"batchsize": [], "los...

阿豪boy
11分钟前
0
0
JupyterLab安装地图插件

JupyterLab安装地图插件 (本文所述软件还在发展之中,欢迎加入开源项目,提供建议、测试和开发。) 在Jupyter中进行数据分析时,往往需要将数据叠加到地图上。简单的可以利用matplotlib/ec...

openthings
20分钟前
0
0
Coding and Paper Letter(八)

资源整理 1 Coding: 1.Python项目,由Allen Downey撰写的Think Python第二版的LaTeX源代码和支持代码。 ThinkPython2 2.R语言包h3jsr,h3jsr使用V8的神奇力量通过其javascript绑定提供对Ube...

胖胖雕
28分钟前
0
0
skiplist跳跃表

插入删除log(N) TODO

梦想游戏人
29分钟前
1
0
利用世界杯,读懂 Python 装饰器

Python 装饰器是在面试过程高频被问到的问题,装饰器也是一个非常好用的特性, 熟练掌握装饰器会让你的编程思路更加宽广,程序也更加 pythonic。 今天就结合最近的世界杯带大家理解下装饰器。...

p柯西
43分钟前
0
0
Xshell登录阿里云服务器ECS

Xshell登录阿里云服务器ECS 1. 参考资料: 1). 《阿里云服务器怎么用?阿里云服务器使用教程》 链接:http://www.cr173.com/html/50758_1.html 2). eagle-zhang的CSDN博客《Xshell连接不上阿...

SuShine
52分钟前
1
0
IDEA中的HTTP Client Editor测试API

在前后端分离项目,前后端通过api进行通信。如果用postman免费版进行api测试的话,由于无法保存测试脚本到文件,不方便前端查看。 你可以选择付费版。也可以利用IDEA自带的HTTP Client Edito...

hutaishi
55分钟前
0
0
解决“只能通过Chrome网上应用商店安装该程序”的方法

摘要 : 最近有些用户反映某个Chrome插件在安装的时候,提示“只能通过Chrome网上应用商店安装该程序”,为了解决这一问题,Chrome插件网带来了相关的解决方法。 某些用户在Chrome插件网下载了...

沧海一刀
56分钟前
0
0
通过UNIX域套接字传递文件描述符

  传送文件描述符是高并发网络服务编程的一种常见实现方式。Nebula 高性能通用网络框架即采用了UNIX域套接字传递文件描述符设计和实现。本文详细说明一下传送文件描述符的应用。 1. TCP服务...

Bwar
59分钟前
0
0
python操作Excle

# -*- coding: utf-8 -*-from openpyxl import load_workbook, Workbook#index:第几个sheet页,第一个sheet页的index为0def readExcle(filename,index): # 加载excle文件 wb = l......

淺陌离殇
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部