`

Java的Integer与int互转

阅读更多
int转Integer
int i = 0;
Integer wrapperi = new Integer(i);


Integer转int
Integer wrapperi = new Integer(0);
int i = wrapperi.intValue();




JDK1.5以后的int转Integer
JDK1.5以后,Java为我们提供了更为丰富的转换方法。

其中最值得一提的就是自动装包/自动拆包(AutoBoxing/UnBoxing)。
此功能大大丰富了基本类型(primitive type)数据与它们的包装类(Wrapper Class)
的使用。

由于AutoBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
int i = 0;
Integer wrapperi = i;


还有其他方法?
JDK1.5为Integer增加了一个全新的方法:
public static Integer valueOf(int i)

以下代码在JDK1.5的环境下可以编译通过并运行。
int i = 0;
Integer wrapperi = Integer.valueOf(i);


此方法与new Integer(i)的不同处在于:
方法一调用类方法返回一个表示指定的 int 值的 Integer 实例。
方法二产生一个新的Integer对象。

JDK API文档中对这个新的valueOf方法有明确的解释:
如果不需要新的 Integer 实例,则通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。

但这个解释有点晦涩难懂。为什么该方法有可能通过缓存经常请求的值而显著提高性能?

通过反编译工具查看valueOf方法。
 /*  
  * 返回一个表示指定的 int 值的 Integer 实例。如果不需要新的 Integer 实例,则  
  * 通常应优先使用该方法,而不是构造方法 Integer(int),因为该方法有可能通过  
  * 缓存经常请求的值而显著提高空间和时间性能。   
  * @param  i an <code>int</code> value.  
  * @return a <tt>Integer</tt> instance representing <tt>i</tt>.  
  * @since  1.5  
  */  
public static Integer valueOf(int i) {   
      final int offset = 128;   
      if (i >= -128 && i <= 127) { // must cache    
        return IntegerCache.cache[i + offset];   
     }   
     return new Integer(i);   
}  


可以看到对于范围在-128到127的整数,valueOf方法做了特殊处理。
采用IntegerCache.cache[i + offset]这个方法。
从名字,我们可以猜出这是某种缓存机制。

进一步跟踪IntegerCache这个类,此类代码如下
/*  
  * IntegerCache内部类  
  * 其中cache[]数组用于存放从-128到127一共256个整数  
  */  
private static class IntegerCache {   
    private IntegerCache(){}   
  
    static final Integer cache[] = new Integer[-(-128) + 127 + 1];   
  
    static {   
        for(int i = 0; i < cache.length; i++)   
        cache[i] = new Integer(i - 128);   
    }   
}  


这就是valueOf方法真正的优化方法,当-128=<i<=127的时候,返回的是IntegerCache中的数组的值;当 i>127 或 i<-128 时,返回的是Integer类对象。

再举一个经常被提到的例子
Integer i=100;
Integer j=100;
//print true
System.out.println(i==j);

此时的 i=IntegerCache.cache[i + 128] = IntegerCache.cache[228],
同样j = IntegerCache.cache[j + 128] = IntgerCache.cache[228]
因此 Integer引用i中存储的是cache数组第228号元素的地址。同理j也是同一个cache数组的第228号元素的地址(因为cache是Integer的static数组,只有一个)。
i==j比较的是引用地址,因此返回true。

Integer i=200;
Integer j=200;
//print false
System.out.println(i==j); 

此时的 i=new Integer(200);  同样j=new Integer(200) 。
两次都在堆中开辟了Integer的对象。
i 和 j 中存储的堆的对象地址是完全不同的。i==j 自然返回false。


引入缓存机制的作用何在?

接着上面的例子,假如我们在编程时大量需要值为100(100的范围在-128到127之间)的Integer对象。如果只能通过new来创建,需要在堆中开辟大量值一样的Integer对象。
这是相当不划算的,IntegerCache.cache很好的起到了缓存的作用。
当我们需要Integer i  = 100的时候,直接从cache中取出第[100+128]号元素的地址赋值给引用i,再次需要Integer j = 100时,还是直接去这个地址赋值给j。是不是省去了在堆中不停的创建对象的代价了(空间,时间上的消耗都很大)。 这就是valueOf方法真正的提高性能之处。
正如JDK API文档对valueOf(int i)方法的描述,该方法有可能通过缓存经常请求的值而显著提高空间和时间性能。

结论

valueOf(int i)的优化只针对于范围在-128到127的整数。




JDK1.5以后的Integer转int
由于UnBoxing的存在,以下代码在JDK1.5的环境下可以编译通过并运行。
Integer wrapperi = new Integer(0);
int i = wrapperi;








附:AutoBoxing与UnBoxing带来的转变
在JDK1.5之前,我们总是对集合不能存放基本类型而耿耿于怀。

以下代码在JDK1.5中成为了可能,试想下在JDK1.5之前该如何实现这段代码?
int x = 1; 
Collection collection = new ArrayList(); 
collection.add(x);//AutoBoxing,自动转换成Integer. 
Integer y = new Integer(2); 
collection.add(y + 2); //y + 2为UnBoxing,自动转换成int。之后再次转换为Integer。


此特性同样适用于Map
Map map = new HashMap();
int x = 1;
Integer y = new Integer(2);
int z = 3;
map.put(x,y + z);//x自动转换成Integer。y+z自动转换成int。之后再次转换为Integer。
5
2
分享到:
评论
3 楼 Nabulio 2016-08-17  
是不错的
2 楼 shihengli2010 2016-06-28  
学习了 !
Integer i = 100;
Integer j = 100;
System.out.println(i==j);

Integer i1 = 200;
Integer j1= 200;
System.out.println(i1==j1);
居然打印的是不同的结果。
1 楼 flex涵 2015-05-04  
还可以,差不多就是这个意思.

相关推荐

    Java中Integer两种转int方法比较

    在Java编程语言中,将`Integer`对象转换为基本数据类型`int`有两种常见的方法:`Integer.parseInt()`和`Integer.valueOf()`。理解这两种方法的区别和应用场景对于编写高效且正确的Java代码至关重要。 首先,我们来...

    JAVA-int和Integer的区别

    在Java编程语言中,`int`和`Integer`都是用于表示整数值的数据类型,但它们之间存在着显著的差异。理解这些区别对于编写高效且优化的Java代码至关重要。 首先,`int`是Java中的原始数据类型(Primitive Type),它...

    java中long类型转换为int类型-java long转int.pdf

    第三种方法是先将 `long` 类型的值转换为 `String`,然后再通过 `Integer.parseInt()` 将字符串解析为 `int`。这种方法比较间接,但可以避免直接转换时的溢出异常。不过,如果原始 `long` 值超出 `int` 范围,`...

    JAVA-int和Integer的区别1.zip

    在Java编程语言中,`int`和`Integer`都是用于表示整数值的数据类型,但它们之间存在着显著的差异。理解这些区别对于编写高效且优化的Java代码至关重要。 首先,`int`是Java中的原始数据类型之一,它直接存储在栈...

    Integer和int的不同

    在Java编程语言中,`Integer`和`int`是两种不同的数据类型,它们在使用上有一些关键的区别。首先,`int`是Java的八种原始数据类型之一,它用来存储整数值,如-2147483648到2147483647之间的数字。`int`变量的默认值...

    java中int_char_string三种类型的相互转换

    Java 中 int、char、String 三种类型的相互转换详解 Java 作为一种静态类型语言,对变量的类型定义非常严格。然而,在实际开发中,我们经常需要在不同的类型之间进行转换以满足不同的需求。其中,int、char、String...

    Java中int和Integer的区别.doc.doc

    Java 中 int 和 Integer 的区别 在 Java 编程语言中,int 和 Integer 是两种不同的数据类型,虽然它们看起来很相似,但它们有着根本的区别。下面我们将详细探讨这两种数据类型的差异。 基本类型 vs 复杂数据类型 ...

    java中String类型和int类型比较及相互转换

    在Java中,直接比较一个String类型的值与一个int类型的值是非法的,因为它们属于不同的数据类型。若要进行比较,必须先进行类型转换。 #### 2.1 使用compareTo方法比较String类型 对于两个String类型的比较,可以...

    java中string和int型的相互转换.doc

    Java 中的 String 和 int 类型的相互转换是一个基本的数据类型转换操作,我们可以使用多种方法来实现这种转换,例如使用 `Integer.parseInt()` 方法、`Integer.valueOf()` 方法、`String.valueOf()` 方法等。...

    Java中int和Integer的区别.doc

    int 和 Integer 都可以表示某一个数值,但是它们不能互用,因为它们是不同的数据类型。例如: int n = 40; Integer nI = new Integer(n); ArrayList al = new ArrayList(); al.add(n); // 不可以,因为 int 不能...

    Java中int与integer的区别(基本数据类型与引用数据类型)

    在Java编程语言中,`int` 和 `Integer` 是两种截然不同的数据类型,它们各自具有独特的特性和用途。理解这两者之间的差异对于编写高效、可靠的代码至关重要。 首先,`int` 是Java中的一个基本数据类型,它代表整数...

    JAVA Integer类型自加实例详解

    从字节码中,我们可以看到,Java 编译器将 Integer 对象的自加操作分解成了三个步骤:首先,调用 java.lang.Integer.intValue() 方法将 Integer 对象拆箱成 int 类型的值;然后,对 int 类型的值进行加一操作;最后...

    通过实例了解Java Integer类和int的区别

    Java Integer类和int的区别 Java Integer类和int是Java中两个相关却又不同的概念,很多开发者容易混淆它们之间的区别本文将通过实例来了解Java Integer类和int的区别。 知识点1:自动装箱和拆箱 在Java中,我们...

    Java实现任意进制的转换

    在编程领域,进制转换是一项基础且重要的...以上就是Java实现任意进制转换的方法,包括二进制转十六进制、十进制转任意进制以及36进制加法。理解这些概念和方法,对于理解和编写处理数字系统转换的Java代码至关重要。

    String与int相互转换

    在编程世界中,字符串(String)和整型(int)数据类型是两种常见的数据类型,它们在...以上就是关于Java中String与int相互转换的知识点详解。在实际编程中,理解并熟练掌握这些转换方法将有助于编写高效且健壮的代码。

    JAVA Integer == equal 比较 doc 比较大小 是否相等

    自动装箱是指 Java 编译器在编译时将基本类型 int 转换为 Integer 对象的过程。 使用 "==" 运算符比较 Integer 对象 在 Java 中,"==" 运算符用于比较两个对象的引用是否相同,而不是比较对象的实际值。因此,当...

    Java int与integer的对比区别

    在Java编程语言中,`int` 和 `Integer` 都是用来表示整数的,但它们在性质和使用场景上有着显著的区别。理解这两者之间的差异对于编写高效且符合Java语法规则的代码至关重要。 首先,`int` 是Java中的一个基本数据...

    Java对象和JSON互转换利器-Gson

    Java对象与JSON之间的转换在现代Web开发中至关重要,因为它们是服务器端数据处理和客户端交互的主要格式。Gson是Google提供的一个开源库,专门用于在Java对象和JSON数据之间进行无缝转换。它以其强大、灵活和高效而...

Global site tag (gtag.js) - Google Analytics