Java-整型数值对比

题一:

有如下4条语句:()

Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);

以下输出结果为false的是:

A. System.out.println(i01==i02);
B. System.out.println(i01==i03);
C. System.out.println(i03==i04);
D. System.out.println(i02==i04);

答案:C

解析

  1. 无论如何,Integer与new Integer不会相等。不会经历拆箱过程,
  2. 两个都是非new出来的Integer,如果数在-128到127之间,则是true,否则为false
    java在编译Integer i2 = 128的时候,被翻译成-> Integer i2 = Integer.valueOf(128);而valueOf()函数会对-128到127之间的数进行缓存
  3. 两个都是new出来的,都为false
  4. int和integer(无论new否)比,都为true,因为会把Integer自动拆箱为int再去比
  • Integer valueOf(int i):返回一个表示指定的 int 值的 Integer 实例。

Byte,Short,Integer,Long,Character这5种整型的包装类也只是在对应值小于等于127并且大于等于-128时才可使用常量池,因为他们至占用一个字节(-128~127);

再者Integer.valueOf方法中也有判断,如果传递的整型变量>= -128并且小于127时会返回IntegerCache类中一个静态数组中的某一个对象, 否则会返回一个新的Integer对象,代码如下

public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}

一些基本数据类型缓冲池的范围
boolean values true and false
short values between -128 and 127
int values between -128 and 127
char in the range \u0000 to \u007F
进入对应类源码查看对应XXXCache类的cache范围即可

所以如果你测试如下代码

public static void main(String[] args) {

Integer a = 127;
Integer b = 127;

Integer c = 128;
Integer d = 128;

System.out.println(a == b);
System.out.println(c == d);
}

结合自动封装、常量池以及Integer.valueOf方法就不难得出,答案时true和false;

再看本题

Integer i01=59;
int i02=59;
Integer i03=Integer.valueOf(59);
Integer i04=new Integer(59);

第一行:由于59在-128~127范围之内,所以在自动装箱的时候,会返回IntegerCache[59 - (-128)];

第三行:同第一行

第四行:因为有new关键字,所以在heap中开辟了一块新内存放置值为59的Integer对象。

System.out.println(i01==i02);//正确
System.out.println(i01==i03);//正确,都指向IntegerCache[59-(-128)]对象
System.out.println(i03==i04);//错误,引用指向的对象地址不同
System.out.println(i02==i04);//正确

题二:

int i = 12;
Integer j = new Integer(12);
j.equals (i) ;
i == j

jdk1.5之后,下列 java 程序输出结果为______。

A: true,false
B: true,true
C: false,true
D: false,false
E: 对于不同的环境结果不同
F: 程序无法执行

答案:B

解析

①比较的是值

一、基本数据类型与引用数据类型进行比较时,引用数据类型会进行拆箱,然后与基本数据类型进行值的比较

举例:
int i = 12;
Integer j = new Integer(12);
i == j 返回的是true

二、引用数据类型与基本数据类型进行比较(equals方法),基本数据类型会进行自动装箱,与引用数据类型进行比较,Object中的equals方法比较的是地址,但是Integer类已经重写了equals方法,只要两个对象的值相同,则可视为同一对象,具体看API文档,所以这归根到底也是值的比较!

举例:
int i = 12;
Integer j = new Integer(12);
j.equals(i) 返回的是true

②比较的是地址

一、如果引用数据类型是这样 Integer i = 12;直接从常量池取对象,这是如果数值是在-128与127之间,则视为同一对象,否则视为不同对象

举例:
Integer i = 12; Integer j = 12; i == j 返回的是true
Integer i = 128; Integer j = 128; i == j 返回的是false

二、如果引用数据类型是直接new的话,不管值是否相同,这时两个对象都是不相同的,因为都会各自在堆内存中开辟一块空间

举例:
Integer i =new Integer(12);
Integer j = new Integer(12);
i == j 这时返回的是false
三、从常量池取对象跟new出来的对象也是不同的
举例:
Integer i = 12;
Integer j = new Integer(12)
i == j 这时返回的是false,因为第二个语句其实已经是new了两个对象了!!!