`
kingxianstar
  • 浏览: 20180 次
  • 性别: Icon_minigender_1
  • 来自: 北京
最近访客 更多访客>>
社区版块
存档分类
最新评论

String转Integer源码分析

阅读更多
今天参加了开发类的面试,面试官问了我一个问题,给你一个String ,让你转换为Int。我说用ParseInt()方法进行转化,没想到他说不要用这个现成的方法,我当时还真没想到。回来上网查了一下,看了parseInt()的源代码 ,豁然开朗!这就是差距啊!

下面是从网上找来的:

我们经常为用到Integer.valueOf(String str)这个方法,如果字符串格式不对,这个方法会抛出一个系统异常NumberFormatException
这里我们就要分析一下这个方法,其中Byte,Short也是调用了Ingeter中的方法.
在Integer类中的定义如下:
public static Integer valueOf(String s) throws NumberFormatException
    {
return new Integer(parseInt(s, 10));
    }
这里因为parseInt方法返回的int型的,这里调用了一个构造函数产生了一个新的Integer实例.
这里关心的是parseInt方法,该方法代码如下:
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, max = s.length();
int limit;
int multmin;
int digit;

if (max > 0) {
     if (s.charAt(0) == '-') {
  negative = true;
  limit = Integer.MIN_VALUE;
  i++;
     } else {
  limit =- Integer.MAX_VALUE;
     }

     if (i < max) {
  digit = Character.digit(s.charAt(i++),radix);
  if (digit < 0) {
      throw NumberFormatException.forInputString(s);
  } else {
      result = -digit;
  }
     }
     while (i < max) {
         // 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);  异常1
  }
  result *= radix;
  if (result < limit + digit) {
      throw NumberFormatException.forInputString(s);  异常2
  }
  result -= digit;
     }
} else {
     throw NumberFormatException.forInputString(s);
}

if (negative) {
     if (i > 1) {
  return result;
     } else { /* Only got "-" */
  throw NumberFormatException.forInputString(s);
     }
} else {
     return -result;
}
    }

很显然,该方法的第二个参数表示是基数(最常用的是十进制,还有十六机制,八进制等等).
如果字符串是空指针,直接抛出异常.
如果基础小于2或者大于36的话,抛出异常(这种情况一般不会出现,因为我们用的最多就是十进制的了).
如果是空字符串,也抛出异常,也就是max=0的情况了.
我们来关注下面的转换过程:
这里使用了Character中的静态方法digit,这个方法比较复杂,这里先说明它的功能:对于给定的基数,如果是合法的字符(可以转化为数字),返回该数字值,否则返回-1.比如digit('3',10)返回3,digit('a',10)返回-1.
这段程序看起来很简单,其实还真不容易看懂,这里先说明几个局部变量的含义吧:
result:记录返回值
negative:符号标志
i:字符串位置
s:字符串长度
limit:界限
multmin:也是一个界限
digit:当前字符表示的数字
先看第一个字符是否是'-'号,设定符号标志negative和极限值limit.
注意到limit一定是一个负值.
处理最高位,这里result保存的是负值,这样就可以对正负数统一处理.
关键就是这个while循环了,第一个if不用解释了,肯定是因为非法字符.
第二个if语句的含义:如果result小于multmin,会产生什么结果呢?
是不是一定会溢出呢?假设不会溢出,就是说结果必须>=limit.
result小于multmin,result至少应该位multmin-1,后面有result=result*radix=(multmin-1)*radix=multmin*radix-radix
该值肯定小于limit,其中multmin=limit/radix,注意这里都是负数.
所以假设不成里,如果result小于multmin的话,后面一定会溢出.
如果这里没有判断的话,溢出就麻烦了,正数也会变负数了.
第三个if语句的含义:在这条语句以前肯定没有溢出,但是有可能加上最后一位digit就溢出了,所以这个判断也是必要的.
后面的就比较好理解了,else是表示空字符串"".
如果是负数的还要看是否长度是1,就只是一个'-'号的情况.
如果是正数的话返          回相反数就可以了.
这里有好多地方都有可能抛出异常,只要看明白了程序就知道这个异常是那条语句抛出的了,这里考虑溢出异常:异常1和异常2.
Ingeter.Max_VALUE=2147483647
下面的两条语句在不同的地方抛出异常.
Ingeter.valueOf("2147483648");这个在异常2抛出的.
Ingeter.valueOf("21474836471");这个在异常1抛出的.

这里简单的分析了String转化为Ingeter的过程,其实整个Ingeter类也就主要是这个方法了,Byte和Short都是调用这个方法的.
看看Byte的代码:
public static byte parseByte(String s, int radix)
throws NumberFormatException {
int i = Integer.parseInt(s, radix);
if (i < MIN_VALUE || i > MAX_VALUE)
     throw new NumberFormatException(
                "Value out of range. Value:\"" + s + "\" Radix:" + radix);
return (byte)i;
   }

了解这个方法后就再也不会为Integer.valueOf()产生的异常感到意外了,特别是在JSP中,因为参数都是String型的,转换的时候动不动就出现异常,你该知道怎么回事了吧.   
分享到:
评论

相关推荐

    convert string to integer

    此外,标签中提到的“源码”可能指的是博客作者对`to_i`和`Integer`方法的内部实现进行了简要分析。这些方法在Ruby的C语言实现中是复杂的,涉及到字符扫描、错误处理和数值计算。虽然对于大多数开发者来说,了解其...

    String与int相互转换

    源码分析可以帮助我们理解这些转换过程的底层逻辑和性能影响。 4. 工具支持: 开发者工具如IDEA、Eclipse等提供了很多便捷的功能,比如自动转换和格式化,使得在实际编码过程中进行String和int的转换更加轻松。 5...

    FreeRadius源码分析之-radius.h

    此外,文件还定义了系统自身数据类型,如 `PW_TYPE_STRING`、`PW_TYPE_INTEGER` 和 `PW_TYPE_IPADDR` 等,这些类型用于表示不同类型的radius属性值,如字符串、整数和IP地址。 在radius协议中,属性类型是非常关键...

    32进制转10进制 delphi 源码

    本文将深入探讨如何在Delphi中实现32进制到10进制的转换,并提供相关的源码分析。 32进制(或称为二进制的扩展形式)是一种表示数值的方式,它使用32个不同的符号(通常是0-31)来表示数值。与二进制类似,每个位的...

    openssl源码分析

    ### OpenSSL源码分析知识点梳理 #### 一、基础知识 **1.1 对称算法** - **定义**: 对称加密算法是指加密和解密使用相同密钥的加密算法。 - **常见算法**: 包括DES(Data Encryption Standard)、AES(Advanced ...

    ThreadLocal源码分析和使用

    ThreadLocal 源码分析和使用 ThreadLocal 是 Java 语言中的一种多线程编程机制,用于解决多线程程序的并发问题。它不是一个 Thread,而是一个 Thread 的局部变量。ThreadLocal 的出现是为了解决多线程程序中的共享...

    Java rt.jar 源码分析

    例如,`java.lang`包是最基础的包,包含了一些基本类型类的包装类,如`Integer`、`String`,以及系统相关的类,如`System`、`Class`。`java.util`包提供了集合框架、日期时间、队列、映射等工具类。`java.io`和`java...

    Map排序

    标签中的“源码”可能是指分析Map排序的底层实现,比如HashMap和TreeMap的源代码,这可以帮助我们理解它们的工作原理和效率。而“工具”可能是指使用Java内置的工具类,如Collections.sort()和TreeMap,来进行排序...

    TINY部分源码分析报告[文].pdf

    《TINY源码分析》 TINY是一款小型的编译器,它的源代码结构清晰,易于理解,适合学习编译原理。本文将深入探讨TINY的源码,主要围绕其核心模块进行分析。 首先,TINY的主要执行入口在`MAIN.C`文件中。在这个文件里...

    java8集合源码分析-JUC:高并发与多线程

    集合源码分析 高并发与多线程 Stargazers over time 线程 线程的创建和启动 线程的sleep、yield、join 线程的状态 代码在 部分。 synchronized关键字(悲观锁) synchronized(Object) 不能用String常量、Integer、Long...

    big integer

    例如,`to_string()`方法可以将大整数转换为十进制字符串,而`from_string(const char*)`可以将字符串解析为大整数。 5. **内存管理**:由于大整数的大小不固定,需要考虑动态分配和释放内存。可能会有成员函数如`...

    VB写的进制转换(含源码)

    本篇文章将详细探讨如何在VB中进行16进制与10进制之间的转换,并提供含源码的实例分析。 首先,我们需要理解不同进制之间的关系。十进制是我们日常生活中最常用的计数系统,基数为10。而十六进制是一种逢16进一的...

    delphi进制转换源码

    ### Delphi 进制转换源码解析与应用 在计算机科学中,数据的表示和转换是基础而重要的概念。不同的进制系统(如二进制、八进制、十进制和十六进制)在编程中有着广泛的应用,尤其是在硬件交互、数据存储和网络通信...

    Android AsyncTask 源码解析

    public class MyTask extends AsyncTask&lt;String, Integer, String&gt; { @Override protected String doInBackground(String... params) { // 在后台线程执行耗时操作 return "Result"; } @Override protected ...

    VB制进制转换,有小数,有源码

    Function ConvertToBase(ByVal decimalNum As Double, ByVal base As Integer) As String '... End Function Function ConvertFromBase(ByVal numStr As String, ByVal base As Integer) As Double '... End ...

    AsyncTask 源码解析

    本文将深入探讨 AsyncTask 的内部实现原理、工作流程以及关键代码分析。 首先,AsyncTask 有三个泛型参数,分别代表输入参数类型(Params)、进度更新参数类型(Progress)和结果参数类型(Result)。通过这些参数...

    leveldb源码分析

    ### Leveldb源码分析 #### 一、概述 Leveldb是由Google开发的一款高性能键值存储系统,它的设计目标是在单机上提供高效、可靠的数据存储服务。Leveldb采用Log-Structured-Merge Tree(LSM树)作为其核心数据结构,...

    VB有符号十六进制转十进制工具,附源码

    在IT行业中,编程语言是构建各种软件和工具的基础,Visual Basic(VB)作为一款流行的编程环境,被广泛用于开发各种...通过查看和分析源码,开发者可以学习到关于进制转换、字符串处理、条件判断等多方面的编程技巧。

Global site tag (gtag.js) - Google Analytics