我们知道,所有整数都是通过二进制编码的形式存储在内存中的。比如32位的整数,最高位是符号位,0代表正数,1代表负数。

那么怎么才能够将整数的二进制编码形式打印出来呢?Integer类提供了一个公有静态方法toBinaryString能够达到这一目的。我们来看看这段源码:

public static String toBinaryString(int i)
{
return toUnsignedString(i, 1);
} /**
* Convert the integer to an unsigned number.
*/
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));
}

可以看到,实际上是通过调用toUnsignedString方法来实现的。这段代码的精妙之处在于以下几点:

1. 掩码mask的计算。shift参数用于区分不同进制,比如二进制的shift=1,mask=1;八进制的shift=3,mask=7;十六进制的shift=4,mask=15。

2. 右移使用的是>>>而不是>>。位运算中的右移分为算术右移(>>)和逻辑右移(>>>)。在进行算术右移时,最高位补符号位;而在进行逻辑右移时,最高位补0。如果这里使用的算术右移,那么对于像-1这样的负数,不论进行多少次右移操作都不可能变成0,所以会造成死循环。

3. 使用的是do-while而不是while。这是一个极其重要的细节,如果使用的是while,那么对于i=0的场景则会返回空字符串。

JDK源码解读之toUnsignedString的更多相关文章

  1. Timer的故事----Jdk源码解读

    咱们今天也来说说定时器Timer Timer是什么? Timer  n. [电子] 定时器:计时器:计时员 从翻译来看,我们可以知道Timer的本意是,定时定点. 而JDK中Timer类也的确是这个本 ...

  2. HashTable的故事----Jdk源码解读

    HashTable的故事 很早之前,在讲HashMap的时候,我们就说过hash是散列,把...弄碎的意思.hashtable中的hash也是这个意思,而table呢,是指数据表格,也就是说hasht ...

  3. HashSet的故事----Jdk源码解读

    Hash,我们在说HashMap的时候,已经知道Hash是散列,Map是映射了. 那么Set又是什么呢 ? 先来看看Set的翻译是什么 n. [数] 集合:一套:布景:[机] 装置 这里Set所取的含 ...

  4. Java是如何实现自己的SPI机制的? JDK源码(一)

    注:该源码分析对应JDK版本为1.8 1 引言 这是[源码笔记]的JDK源码解读的第一篇文章,本篇我们来探究Java的SPI机制的相关源码. 2 什么是SPI机制 那么,什么是SPI机制呢? SPI是 ...

  5. JDK容器类Map源码解读

    java.util.Map接口是JDK1.2开始提供的一个基于键值对的散列表接口,其设计的初衷是为了替换JDK1.0中的java.util.Dictionary抽象类.Dictionary是JDK最初 ...

  6. JDK容器类List,Set,Queue源码解读

    List,Set,Queue都是继承Collection接口的单列集合接口.List常用的实现主要有ArrayList,LinkedList,List中的数据是有序可重复的.Set常用的实现主要是Ha ...

  7. Jfinal启动源码解读

    本文对Jfinal的启动源码做解释说明. PS:Jfinal启动容器可基于Tomcat/Jetty等web容器启动,本文基于Jetty的启动方式做启动源码的解读和分析,tomcat类似. 入口  JF ...

  8. AbstractQueuedSynchronizer源码解读

    1. 背景 AQS(java.util.concurrent.locks.AbstractQueuedSynchronizer)是Doug Lea大师创作的用来构建锁或者其他同步组件(信号量.事件等) ...

  9. ScheduledThreadPoolExecutor源码解读

    1. 背景 在之前的博文--ThreadPoolExecutor源码解读已经对ThreadPoolExecutor的实现原理与源码进行了分析.ScheduledExecutorService也是我们在 ...

随机推荐

  1. 如何让一个DIV浮动在另一个DIV上面

      直接上DEMO了 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3 ...

  2. ThinkPHP 3.2 模板中的Angularjs 的变量{{$first}} 无法被解析

    ThinkPHP 3.2 模板中的Angularjs 的变量"{{$first}}" 无法被解析, 模板解析冲突,例如在angularjs 的变量"{{$first}}& ...

  3. python 中的[::-1]

    for value in rang(10)涉及的数字倒序输出: for value in rang(10)[::-1]涉及的数字倒序输出: 一.反转 二.详解 这个是python的slice nota ...

  4. Oracle数据库字段类型说明

    目前Oracle 数据库大概有26个字段类型,大体分为六类,分别是字符串类型.数字数据类型.日期时间数据类型.大型对象(LOB)数据类型.RAW和LONG RAW数据类型.ROWID和UROWID数据 ...

  5. python mysql操作

    引入数据库的包 import MySQLdb 连接数据库conn=MySQLdb.connect(host='localhost',user='root',passwd='123456',db='te ...

  6. stm32cube--通用定时器--产生pwm波

    看了通用定时器的资料,发现内容挺多,挺难看懂,现在还是先掌握使用方法,以后再多看几遍吧. ① ② ③生成mdk工程后,在main.c的while(1)前面加上HAL_TIM_PWM_Start(&am ...

  7. urlencode 和 rawurlencode 的区别

    urlencode和rawurlencode的区别urlencode和rawurlencode的区别 $str1 = urlencode(':/?= &#'); $str2 = rawurle ...

  8. LoarRunner11使用异常及解决方案

    1:使用VuGen录制后出现“由于另一个程序正在运行中,此操作无法完成.请选择切换到来激活正在运行中的程序,并更正问题”,点击“切换到”无效果. 解决:在“运行”中输入“msconfig”,选择“启用 ...

  9. 类库、委托、is as运算符、泛型集合

    类库: 说白了,就是让别人调用你写的方法,并且不让别人看到你是怎么实现的. 如果有功能你不会做,需要别人帮忙,那么你的同事可以帮你写好一个类,然后你来调用这个类中的方法,完成你的项目. 1.C#源代码 ...

  10. Android 之 log

    android.util.Log常用方法: Log.v()  VERBOSE  任何消息都会输出 Log.d()  DEBUG  仅输出debug调试的意思,但他会输出上层的信息,过滤起来可以通过DD ...