Integer与int

首先,需要厘清一些概念:
1、Integer是一个类,用Integer声明一个变量其是一个对象类型(或者说引用类型);int是基本类型,用int声明的变量是非对象类型,即不能在其上调用方法。
2、“==”作用于对象上的时候,其比较的是对象的引用本身的值(或者说对象的地址更容易理解),而作用于基本类型的时候比较的就是基本类型的值。

接下来看一段代码:

public class Test {

    public static void main(String[] args) {

        Integer i1 = 2;

        int i2 = 2;

        System.out.println(i1 == i2);

    }

}

在这段代码中有两个令人困惑的问题,首先是将一个基本类型的值赋值给对象的引用,即Integer i1 =2;其次是拿一个对象类型和一个基本类型比较。按理说这两种做法肯定都是有问题的,在jdk1.4(若使用的jdk版本是1.5或之后的版本中,可以使用javac -source 1.4 Test.java来编译)上,确实如此,第一个问题在编译时会报“不兼容的类型”错误,第二个问题会报“运算符 == 不能应用于 java.lang.Integer,int”的错误。

但是jdk1.5引入的自动装箱和自动拆箱,那么,必然要将其中的一种类型转换成另一种类型,究竟是将Integer对象i1转换成int基本类型呢?还是将int基本类型的i2转换成Integer对象?通过javap -c Test反编译Test.class文件就知道答案了:

public static void main(java.lang.String[]);

  Code:

   0:   iconst_2

   1:   invokestatic    #2; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;

   4:   astore_1

   5:   iconst_2

   6:   istore_2

   7:   getstatic       #3; //Field java/lang/System.out:Ljava/io/PrintStream;

   10:  aload_1

   11:  invokevirtual   #4; //Method java/lang/Integer.intValue:()I

   14:  iload_2

   15:  if_icmpne       22

   18:  iconst_1

   19goto    23

   22:  iconst_0

   23:  invokevirtual   #5; //Method java/io/PrintStream.println:(Z)V

   26return

}

其中,[0-4]是Integer i1 = 2的实现,我们发现,编译的字节码里调用了Integer.valueOf方法,因此Integer i1 = 2编译后就等同于Integer i1 = Integer.valueOf(2);[5,6]是int i2 = 2的实现;[7,23]是System.out.println(i1 == i2)的实现,也容易看到,里面调用了Integer.intValue()方法。因此,这个i1 == i2这两个不同类型的变量比较,在编译的时候,编译器是将其转换成相同的类型进行比较的,即将对象类型转换成基本类型,System.out.println(i1 == i2)就等同于System.out.println(i1.intValue() == i2),前面说了,“==”作用于基本类型的时候比较的就是基本类型的值,两个值都是2,所以结果是true。

另外一个令人困惑的例子就是:

public class Test {

    public static void main(String[] args) {

        Integer i1 = 127;

        Integer i2 = 127;

        System.out.println(i1 == i2);

        Integer i3 = 128;

        Integer i4 = 128;

        System.out.println(i3 == i4);

    }

}

运行后发现,i1==i2的结果为true,i3==i4的结果为false?这令不知原因的人头疼不已。在前面一个例子里我们已经说过,诸如Integer i1 = 127,在编译后就等同于Integer i1 = Integer.valueOf(127),既然是调用一个方法来获得对象,那么就有必要对valueOf方法一探究竟了。我们看下源码:

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);

}

到此应该恍然大悟了,IntegerCache缓存了[-128,127]之间的Integer对象,如果valueOf的参数i处于这之间,就返回缓存的对象。否则就new一个新的Integer。前面已经说过,“==”作用于对象上的时候,其比较的是对象的地址,例子中的i1和i2都是从缓存中拿的,当然是同一个对象,i3和i4都是通过new Integer获得的,当然不是同一个对象了。

类似地,java.lang.Long,java.lang.Short分别缓存了[-128,127]之间的Long和Short对象,java.lang.Byte缓存了所有的对象,java.lang.Character缓存了[0,127]之间的Character对象。java缓存这些对象是为了性能优化,既然我们已经知道其缓存了这么些对象,在需要new Integer/Long/…的地方,可改用Integer/Long/Short…#valueOf方法。

时间: 2024-10-24 09:13:19

Integer与int的相关文章

Java进阶(三十四)Integer与int的种种比较你知道多少?

Java进阶(三十四)Integer与int的种种比较你知道多少? 前言 如果面试官问Integer与int的区别:估计大多数人只会说到两点:Ingeter是int的包装类,注意是一个类:int的初值为0,Ingeter的初值为null.但是如果面试官再问一下Integer i = 1;int ii = 1; i==ii为true还是为false?估计就有一部分人答不出来了,如果再问一下其他的,估计更多的人会头脑一片混乱.所以我对它们进行了总结,希望对大家有帮助. 首先看代码: package

Java包装类,以及Integer与int之间的比较

一.Java的基本类型 Java语言中提供了八种基本类型,包括六种数字类型(四个整数型,两个浮点型),一种字符类型,还有一种布尔型. 整数型,包括byte.short.int.long,默认初始值是0: 浮点型,包括float.double,默认初始值是0.0: 字符型,char型,默认值是'',注意跟""的区别,''是字符的引号,""是字符串的引号,两者不同. 布尔型,boolean,默认初始值是false. 注意:如果不初始化一个char类型的变量,将它输出在c

Integer与int的区别

简述:int与Integer的区别: 对于它们,我们可能只是知道简单的区别.Integer是int的一个封装类,int的初始值为0,而Integer的初始值为null.但是他们之间真的仅仅只有这些区别吗?我觉得答案是否定的,于是我决定深入到jdk源码中一探究竟.看看Integer与int到底有什么区别. 执行代码: 1 public class IntegerTest { 2 3 public static void main(String[] args) { 4 // TODO Auto-ge

详解Integer.toString(int i)方法和String.valueOf(int i)方法

通过查看String类的源码: public static String valueOf(int i) { return Integer.toString(i); } 我们可以看到,String.valueOf(int i)其实是调用了Integer.toString(int i)方法的. 再次通过查看Integer类的源码我们可以看到: public static String toString(int i) { if (i == Integer.MIN_VALUE) return "-214

Java数据类型中String、Integer、int相互间的转换

1.Integer转换成int的方法 Integer i;  int k = i.intValue(); 即Integer.intValue(); 2.int转换成Integer int i; Integer it = new Integer(i); 3.String转换成int的方法 String str = "10";   Integer it = new Interger(str); int i = it.intValue(); 即:int i = Integer.intValu

(备忘)Java数据类型中String、Integer、int相互间的转换

1.Integer转换成int的方法 Integer i; int k = i.intValue();即Integer.intValue(); 2.int转换成Integer int i; Integer it = new Integer(i); 3.String转换成int的方法 String str = "10"; Integer it = new Interger(str); int i = it.intValue(); 即:int i = Integer.intValue(st

Integer与int的区别(包装类和基本数据类型的区别)

1. 默认值 int默认值为0,Integer的默认值为null.推论:Integer既可以表示null又可以表示0 2. 包装类中提供了该类型相关的很多算法操作方法 如把十进制装换为2进制(toBinaryString),8进制(toOctalString),16进制(toHexString). 3. 在集合框架中,只能存储对象类型,不能存储基本数据类型. 4. Integer与int是不同的数据类型. 5. 方法中的基本类型变量存储在栈中,包装类型存放于堆中.

Integer与int的种种比较

package com.lxm.basics; public class IntegerTest { public static void main(String[] args) { Integer a1 = 45; int a2 = 45; Integer a3 = Integer.valueOf(45); Integer a4 = new Integer(45); Integer a5 = new Integer(45); System.out.println("a1==a2:"+

Integer 与int类型的区别使用

区别一: Java 为每个原始类型提供了包装类型:  - 原始类型: boolean,char,byte,short,int,long,float,double  - 包装类型:Boolean,Character,Byte,Short,Integer,Long,Float,DoubleInteger与int的区别最基本的是:Ingeter是int的包装类,int的初值为0,Ingeter的初值为null1.自动拆箱比较为true 1 @org.junit.Test 2 public void t

【Java面试题】5 Integer的int 的种种比较?详细分析

如果面试官问Integer与int的区别:估计大多数人只会说道两点,Ingeter是int的包装类,int的初值为0,Ingeter的初值为null.但是如果面试官再问一下Integer i = 1;int ii = 1; i==ii为true还是为false?估计就有一部分人答不出来了,如果再问一下其他的,估计更多的人会头脑一片混乱.所以我对它们进行了总结,希望对大家有帮助. 首先看代码: 1 package com.test; 2 /** 3 * 4 * @author 刘玲 5 * 6 *