您现在的位置是:首页 > 文章 > Java中int与Integer的分析和使用 网站文章

Java中int与Integer的分析和使用

孙玉超 2019-11-06 11:14:46 2 评论 3938 浏览 0 收藏 5


     其实这个问题是蛮简单的,但是工作中,从很多同事代码中发现他们似乎并不是很清楚两者的使用。例如两个Integer类型比较用 == ,或者用Integer1.intValue() == Integer2.intValue(),又或者Integer.intValue() == int。彻底搞清楚这个问题之前,我们需要先了解基本数据类型和引用类型的区别。


1.Java 中的数据类型分为基本数据类型和引用数据类型 

  

     int 是前者而integer 是后者(也就是一个类);因此在进行初始化时int类型的的成员变量初始为0.而Integer类型的成员变量则初始化为null。也就是我们在做项目时一般多数整形字段都会采用Integer的原因。  其次,粗略的说,int类型的变量是存在栈空间的,而Integer类型是引用类型,他的引用存在栈空间,而对象是在堆空间。例如:

Integer example = new Integer(10);

当然,如果在代码中这么写,编译器会告诉我们,这么做是多余的。因为完全可以这样:

Integer example = 10;

这是不是和String有些类似呢?在JDK1.5之后显式手动拆装箱是不必要的 ,所以我们上面两行代码意义相同。举个例子,我们都知道JDK1.5之后引入了泛型机制,泛型是必须使用引用类型的,但是下面的代码是正确的:

List<Integer> test= new ArrayList<>();
int a = 10;
Integer b = 10;
test.add(a);
test.add(b);

这里我们依然可以添加int类型的数据,因为编译器自动给我们装箱成Integer类型了。但是List的泛型不能修改为int。

List<int> list = new ArrayList<>(); //error


2.int和Integer的具体使用方法 


为什么要单独提出这个问题呢,看到项目代码中有以下写法:

if(Integer.valueOf(bid).intValue()== baseButton.getId().intValue()){...}
cookie.setMaxAge(maxAge.intValue());
if(ui.getDeleteMark().intValue() == 1){...}

这对于有强迫症的我来说当然是难受无比的!从上面JDK1.5之后的自动拆装箱之后,我们知道这些调用intValue()的方法都可以省略,即使调用,也是返回当前Integer类的一个int类型final的成员变量。值就是当前的数值。


所以当 Integer 和 int 比较直接用 “==”,当 Integer 和 Integer 比较,用 equals 方法,即可。


具体可以参考Integer类源代码。这些很简单就不多说了。这里重点介绍另一个问题,Integer的缓存机制。看下面的代码:

Integer a= 127;
Integer b= 127;
System.out.println(a == b);//true
Integer c = 128;
Integer d = 128;
System.out.println(c == d);//false
Integer e = 128;
int f = 128;
System.out.println(e == f);//true

第三个结果比较简单,当Integer和int比较时,编译器会将Integer拆箱,所以无论数字是多少,只要相同那么比较结果就是true。那么第一个和第二个结果就值得思考了。如何思考呢,最直接的办法就是看源代码呀!




好的,先解释一下这段英文:返回一个表示指定值的 Integer 实例 int的值。如果没有新的 Integer 实例。需要时,一般应优先使用此方法。构造函数Integer(int),就像这个方法一样,以产生更好的空间和时间性能,缓存频繁请求的值。该方法将始终缓存范围为-128到127的值,包括,并可能缓存此范围之外的其他值。  

我们上面的比较代码实际上是这样的:

Integer a= new Integer(127);
Integer b= new Integer(127);
System.out.println(a == b);//true
Integer c = new Integer(128);
Integer d = new Integer(128);
System.out.println(c == d);//false

那么由上面的解释可以知道在实例化Integer的时候会走上图的逻辑。这里出现了一个叫做IntegerCache的类。当i处于他的高低范围之内,就会不实例化而是返回这个缓存数组的一个元素。IntegerCache是Integer的一个静态内部类。我们可以进一步观察它的代码:




柳暗花明又一村啊,它把-128到127范围内的整数都做了一个缓存,实例化好了放在这里。当我们构造新的Integer的时候会判断新的Integer的整形值是不是在-128~127范围内。如果是,就返回缓存的这个对象。如果不是,再进行实例化操作。节省了频繁的实例化内存开销。仔细看我们会发现,这个上限127是我们自己可以定义的,通过启动参数指定。如果不指定,那么默认是127 。这下我们能弄清楚上面的比较结果了吧。但是实际开发中,我并不建议这么写代码。因为引用类型的比较,一律推荐使用equals方法。但凡是JDK自带的类,基本上都给我们重写好了equals方法,既然如此,为什么要用 == 来比较引用类型呢?除非是真的想比较它们在内存当中的地址!但是好像没有多大意义吧!


转载请注明出处:转载请注明出处

上一篇 : 我的大学 下一篇 : 个人博客,属于我的小世界

留言评论

所有回复

暮色妖娆丶

96年草根站长,2019年7月接触互联网踏入Java开发岗位,喜欢前后端技术。对技术有强烈的渴望,2019年11月正式上线自己的个人博客