parseInt的源码阅读
parseInt的源码阅读
Integer.parseInt()这个方法的功能小巧又实用,实现起来困难不大,没有很复杂。这里就来看一下Java的源码是怎么写的吧,走一边大婶写过的代码,应该会有点收获吧。
其中一条就是,为了考虑程序的健壮性,往往非核心代码占得比较少,相反各种条件判断很多。
/**
* Parses the string argument as a signed integer in the radix
* specified by the second argument.
*
* <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
* </pre></blockquote>
*/
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");
}
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(); // 设置初始位置和字符串的长度
int limit = -Integer.MAX_VALUE;
int multmin;
int digit;
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);
// 字符串的长度为1但是又不是数字, 那肯定就出错了
if (len == 1) // Cannot have lone "+" or "-"
throw NumberFormatException.forInputString(s);
i++;
}
multmin = limit / radix;
/*
* 下面的过程其实很好理解, 以8进制的"534"为例
* (-5*8-3)*8-4 = -348, 根据符号位判断返回的是348
*/
while (i < len) {
// Accumulating negatively avoids surprises near MAX_VALUE
// 除了前面的判断这里的也有点复杂, 因为要考虑到各种进位
// 这个将i位置上的字符根据基数转为实际的值, A->11
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; // 根据符号位来判断返回哪一个
}
没想通的一点是,常理来说(至少我是这样的哈)是考虑用加法,然后再根据符号位判断正负,但是源码中用的是减法。这点没想通是为什么,虽然也没差,感觉怪怪的。
digit = Character.digit(s.charAt(i++),radix);
这里的函数调用里面的代码也挺多的。根据该位上的字符和基数来得到对应的数字。
parseInt的源码阅读的更多相关文章
- jdk源码阅读笔记-Integer
public final class Integer extends Number implements Comparable<Integer> Integer 由final修饰了,所以该 ...
- SpringMVC源码阅读:属性编辑器、数据绑定
1.前言 SpringMVC是目前J2EE平台的主流Web框架,不熟悉的园友可以看SpringMVC源码阅读入门,它交代了SpringMVC的基础知识和源码阅读的技巧 本文将通过源码(基于Spring ...
- Java源码阅读-Integer(基于jdk1.8)
public final class Integer extends Number implements Comparable<Integer> Integer 由final修饰了,所以该 ...
- Spring源码阅读 之 配置的读取,解析
在上文中我们已经知道了Spring如何从我们给定的位置加载到配置文件,并将文件包装成一个Resource对象.这篇文章我们将要探讨的就是,如何从这个Resouce对象中加载到我们的容器?加载到容器后又 ...
- 【原】FMDB源码阅读(三)
[原]FMDB源码阅读(三) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 FMDB比较优秀的地方就在于对多线程的处理.所以这一篇主要是研究FMDB的多线程处理的实现.而 ...
- 【原】FMDB源码阅读(二)
[原]FMDB源码阅读(二) 本文转载请注明出处 -- polobymulberry-博客园 1. 前言 上一篇只是简单地过了一下FMDB一个简单例子的基本流程,并没有涉及到FMDB的所有方方面面,比 ...
- 【原】FMDB源码阅读(一)
[原]FMDB源码阅读(一) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 说实话,之前的SDWebImage和AFNetworking这两个组件我还是使用过的,但是对于 ...
- 【原】AFNetworking源码阅读(六)
[原]AFNetworking源码阅读(六) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 这一篇的想讲的,一个就是分析一下AFSecurityPolicy文件,看看AF ...
- 【原】AFNetworking源码阅读(五)
[原]AFNetworking源码阅读(五) 本文转载请注明出处 —— polobymulberry-博客园 1. 前言 上一篇中提及到了Multipart Request的构建方法- [AFHTTP ...
随机推荐
- papi酱视频因违规遭下线整改,你知道原因吗?
今日4月18日,在微信上的一篇<papi酱遭广电总局封杀 罗振宇1200万恐打水漂>的文章迅速转了起来,说的就是现在网红第一人“papi酱”的视频被广电总局责令下架的消息.箭头直指papi ...
- Spark运行原理解析
前言: Spark Application的运行架构由两部分组成:driver program(SparkContext)和executor.Spark Application一般都是在集群中运行,比 ...
- jqxGrid 绑定格式化
var cellsrenderer = function(row, columnfield, value, defaulthtml, columnproperties) { ) || (row == ...
- 转: KindEditor 图片空间文件增加删除文件、文件夹功能(ASP语言环境)
KindEditor 图片上传功能中集成的图片空间文件管理插件可以对已上传图片进行管理,十分便捷,只是没有图片删除功能,仔细研读xieliang分享的经验后,自己动手改造了一下,顺便分享给有同样需求的 ...
- Cursor use
Ref:http://www.cnblogs.com/Gavinzhao/archive/2010/07/14/1777644.html declare @Id varchar(100),@name ...
- android IntentFilter 使用之 data过滤
1 Intent分为两大类,显式和隐式. 显式事件,就是指通过 component Name 属性,明确指定了目标组件的事件. 比如我们新建一个Intent,指名道姓的说,此事件用于启动名为" ...
- 9.请写出PHP5权限控制修饰符
1.public:public表明该数据成员.成员函数是对所有用户开放的,所有用户都可以直接进行调用 2.private:private表示私有,私有的意思就是除了class自己之外,任何人都不可以直 ...
- 【转】C# Linq 交集、并集、差集、去重
using System.Linq; List<string> ListA = new List<string>(); List<string> ListB = n ...
- Magento开发常用方法
这里是我做Magento开发常用到的方法,现在总结出来,后续会把更多有用的方法总结出来. 1.直接操作数据库 查找数据:$read = Mage::getSingleton("core/re ...
- nodejs框架express实现登录
目录: 访问视图 Post请求 Post请求 - body(1) Post请求 - body(2) Post登陆1 Post登陆2 页面访问控制1 页面访问控制2 访问视图 前面我们已经添加了视图模板 ...