浅谈 Integer 类

  突然发现自己对Integer i = 10;这种语法不太明白,于是乎有了这篇文章,那么在讲解 Integer 之前,我们先看下面这段代码:

public static void main(String[] args) {
	Integer i = 10;
    Integer j = 10;
    System.out.println(i == j);
     
    Integer a = 128;
    Integer b = 128;
    System.out.println(a == b);
    
    int k = 10;
    System.out.println(k == i);
    int kk = 128;
    System.out.println(kk == a);
     
    Integer m = new Integer(10);
    Integer n = new Integer(10);
    System.out.println(m == n);
}

  大家可以先思考一下结果是什么?

  答案是:

  至于为什么是这个结果,下面我们来一一介绍。

1、Integer 类简介

  首先我们大致看一下Integer是什么,Integer 类在JDK1.0的时候就有了,它是一个类,是 int 基本数据类型的封装类。

基本API如下:

  图片引用:http://blog.csdn.net/litong09282039/article/details/46309541

2、Integer 类和 int 的区别

  ①、Integer 是 int 包装类,int 是八大基本数据类型之一(byte,char,short,int,long,float,double,boolean)

  ②、Integer 是类,默认值为null,int是基本数据类型,默认值为0;

  ③、Integer 表示的是对象,用一个引用指向这个对象,而int是基本数据类型,直接存储数值。

3、Integer 的自动拆箱和装箱

  自动拆箱和自动装箱是 JDK1.5 以后才有的功能,也就是java当中众多的语法糖之一,它的执行是在编译期,会根据代码的语法,在生成class文件的时候,决定是否进行拆箱和装箱动作。

  ①、自动装箱

  一般我们创建一个类的时候是通过new关键字,比如:

Object obj = new Object();

  但是对于 Integer 类,我们却可以这样:

Integer a = 128;

  为什么可以这样,通过反编译工具,我们可以看到,生成的class文件是:

Integer a = Integer.valueOf(128);

  这就是基本数据类型的自动装箱,128是基本数据类型,然后被解析成Integer类。

  ②、自动拆箱

  我们将 Integer 类表示的数据赋值给基本数据类型int,就执行了自动拆箱。

Integer a = new Integer(128);
int m = a;

  反编译生成的class文件:

Integer a = new Integer(128);
int m = a.intValue();

  简单来讲:自动装箱就是Integer.valueOf(int i);自动拆箱就是 i.intValue();

4、回顾开头的问题

public static void main(String[] args) {
	Integer i = 10;
    Integer j = 10;
    System.out.println(i == j);
     
    Integer a = 128;
    Integer b = 128;
    System.out.println(a == b);
    
    int k = 10;
    System.out.println(k == i);
    int kk = 128;
    System.out.println(kk == a);
     
    Integer m = new Integer(10);
    Integer n = new Integer(10);
    System.out.println(m == n);
}

  我们使用反编译工具Jad,得到的代码如下:

	public static void main(String args[])
	{
		Integer i = Integer.valueOf(10);
		Integer j = Integer.valueOf(10);
		System.out.println(i == j);
		Integer a = Integer.valueOf(128);
		Integer b = Integer.valueOf(128);
		System.out.println(a == b);
		int k = 10;
		System.out.println(k == i.intValue());
		int kk = 128;
		System.out.println(kk == a.intValue());
		Integer m = new Integer(10);
		Integer n = new Integer(10);
		System.out.println(m == n);
	}

  打印结果为:

  首先,直接声明Integer i = 10,会自动装箱变为Integer i = Integer.valueOf(10);Integer i 会自动拆箱为 i.intValue()。

  ①、第一个打印结果为 true

  对于 i == j ,我们知道这是两个Integer类,他们比较应该是用equals,这里用==比较的是地址,那么结果肯定为false,但是实际上结果为true,这是为什么?

  我们进入到Integer 类的valueOf()方法:

  分析源码我们可以知道在 i >= -128 并且 i <= 127 的时候,第一次声明会将 i 的值放入缓存中,第二次直接取缓存里面的数据,而不是重新创建一个Ingeter 对象。那么第一个打印结果因为 i = 10 在缓存表示范围内,所以为 true。

  ②、第二个打印结果为 false

  从上面的分析我们知道,128是不在-128到127之间的,所以第一次创建对象的时候没有缓存,第二次创建了一个新的Integer对象。故打印结果为false

  ③、第三个打印结果为 true

  Integer 的自动拆箱功能,也就是比较两个基本数据类型,结果当然为true

  ④、第四个打印结果为 true

  解释和第三个一样。int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比较。

  ⑤、第五个打印结果为 false

  因为这个虽然值为10,但是我们都是通过 new 关键字来创建的两个对象,是不存在缓存的概念的。两个用new关键字创建的对象用 == 进行比较,结果当然为 false。 

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏微信公众号:Java团长

Java 动态代理深入解析

要想了解Java动态代理,首先要了解什么叫做代理,熟悉设计模式的朋友一定知道在Gof总结的23种设计模式中,有一种叫做代理(Proxy)的对象结构型模式,动态代...

633
来自专栏云霄雨霁

数据结构----队列

920
来自专栏菩提树下的杨过

mybatis3.2.8 与 hibernate4.3.6 混用

mybatis、hibernate这二个框架各有特色,对于复杂的查询,利用mybatis直接手写sql控制起来更灵活,而一般的insert/update,hib...

1796
来自专栏青枫的专栏

父类中如果没有无参构造方法(也即父类中只给了带参构造方法),子类的构造方法怎么办?

父类中如果没有无参构造方法(也即父类中只给了带参构造方法),子类的构造方法怎么办?

661
来自专栏LinkedBear的个人空间

唠唠SE的集合-02——Iterator迭代器

迭代时如果没有先执行next()则会抛出IllegalStateException,这就意味着必须要先检查是否还有下一个可以被迭代的元素,才能往外取。

863
来自专栏Ryan Miao

java中List对象列表去重或取出以及排序

面试碰到几次list的去重和排序。下面介绍一种做法: 1. list去重 1.1 实体类Student List<Student>容量10k以上,要求去重复。这...

4339
来自专栏每日一篇技术文章

Swift3.0 - 文本输出

591
来自专栏Linyb极客之路

并发编程之Synchronized关键字

一、Synchronized的基本使用 Synchronized是Java中解决并发问题的一种最常用的方法,也是最简单的一种方法。Synchronized的作...

2716
来自专栏闻道于事

Java之集合的遍历与迭代器

集合的遍历 依次获取集合中的每一个元素 将集合转换成数组,遍历数组 //取出所有的学号, 迭代之后显示学号为1004-1009 Object[]...

3265
来自专栏专注研发

JAVA中Sql时间格式与util时间格式转换

  pst.setDate(1, ;//这里的Date是sql中的::得到的是日期

945

扫码关注云+社区