java short相等_Java基础之数据比较Integer、Short、int、short

基础很重要,基础很重要,基础很重要。重要的事情说三遍,。

今天聊一聊Java的数据比较,这个范围比较大,基础类型的比较、引用类型的比较。

前提:

1、Java和c#都提供自动装箱和自动拆箱操作,何为自动装箱,简单点说就是将值类型转换成为引用类型,自动拆箱就是将引用类型转换成为值类型。并且我们还经常被教导,要避免自动的装箱和拆箱操作,因为这个会影响性能。

2、比较常用的运算符是==,equals。

下面分几类来说明数据的比较,

引用类型之间的比较:Integer与Integer之间的比较、Boolean与Boolean之间的比较、Integer与Boolean之间的比较

值类型之间的比较:int与int之间的比较、int与bool之间的比较

值类型与引用类型之间的比较:Integer与int之间的比较、Boolean与bool之间的比较

开工

引用类型之间的比较--Integer与Integer之间的比较

简单说明一下,Integer是引用类型,代表的是整形数字

上代码

public static void main(String[] args) throws Exception {

Integer integer = new Integer(0);

Integer mInteger = Integer.valueOf(0);

Integer sInteger = 0;

System.out.println(integer == mInteger);//false

System.out.println(integer == sInteger);//false

System.out.println(mInteger == sInteger);//true

System.out.println(memoryAddress(integer));

System.out.println(memoryAddress(mInteger));

System.out.println(memoryAddress(sInteger));

}

private static int memoryAddress(Object object) {

// 内存地址会有所不同

return System.identityHashCode(object);

}

执行结果:

20181111224718982331.png

分析:

1、执行结果和我们预想的不太一样,引用类型是在堆上存放的,每个引用的地址应该都不相同。但是mInteger == sInteger  执行结果为true,并且mInteger ,sInteger的内存地址是相同的。

2、要分析这个原因,我们需要了解Java设计者为了性能而进行的一些努力,查看Java源代码,可以看到Integer的valueof方法里面包含了一个缓存:其中IntegerCache.low =-127,IntegerCache.high=128

@HotSpotIntrinsicCandidate

public static Integer valueOf(int i) {

if (i >= IntegerCache.low && i <= IntegerCache.high)

return IntegerCache.cache[i + (-IntegerCache.low)];

return new Integer(i);

}

对于使用Integer.valueof()方法,如果数值是-127至128,那么会使用缓存对象,否则会new一个对象。

3、Integer sInteger = 0;   发生了什么呢?自动装箱,等价于Integer sInteger=Integer.valueOf(0)。通过这个,我们就可以得出比较等于true的原因了,都是从缓存中读取的对象,难怪内存地址会一致。

引用类型比较--Integer与Integer引用类型比较   使用equals

上代码:

public static void main(String[] args) throws Exception {

Integer integer = new Integer(0);

Integer mInteger = Integer.valueOf(0);

Integer sInteger = 0;

System.out.println(integer == mInteger);// false

System.out.println(integer == sInteger);// false

System.out.println(mInteger == sInteger);// true

System.out.println(memoryAddress(integer));

System.out.println(memoryAddress(mInteger));

System.out.println(memoryAddress(sInteger));

System.out.println(integer.equals(mInteger));//true

System.out.println(integer.equals(sInteger));//true

System.out.println(mInteger.equals(sInteger));//true

}

private static int memoryAddress(Object object) {

// 内存地址会有所不同

return System.identityHashCode(object);

}

分析:使用equals比较,只要数值相同,那么比较结果就是相同。查看Java源代码:

public boolean equals(Object obj) {

if (obj instanceof Integer) {

return value == ((Integer)obj).intValue();

}

return false;

}

可以看到Integer的equals比较,其实比较的就是数值。

值类型之间的比较:int与int

上代码

int  m=0;

int i=0;

int s=0;

System.out.println(m==i);//true

//值类型是没有equals方法

//System.out.println(m.equals(i));

分析:对于int 的比较,无需多言,本来就是数值比较。

Integer与int的比较:

Integer integer = new Integer(0);

Integer mInteger = Integer.valueOf(0);

Integer sInteger = 0;// 等价于Integer。valueof

int i = 0;

System.out.println(integer == i);//true

System.out.println(mInteger == i);//true

System.out.println(sInteger == i);//true

System.out.println(integer.equals(i));//true

System.out.println(mInteger.equals(i));//true

System.out.println(sInteger.equals(i));//true

分析:

1、Integer类型与int类型通过==比较,Integer会自动拆箱,转换成int数值进行比较

2、equals方法更是读取对应的int数值进行比较。

因此引用类型与值类型之间的比较,使用equals与==都可以。

简单总结:

1、引用类型之间的比较,由于存在-127至128之间的缓存对象,因此使用== 进行比较存在风险。优先使用equals进行比较

2、引用类型与值类型进行比较,由于会自动拆箱,因此使用==和equals都可以正确得到结果

3、建议在实际编码过程中,对数值的比较使用equals

深入总结:

不仅仅Integer,其他的基本类型也都存在缓存,下面给出一个简单图表进行说明

基本类型

装箱类型

取值范围

是否缓存

缓存范围

byte

Byte

-128~127

-128~127

short

Short

-2^15 ~ (2^15 - 1)

-128~127

int

Integer

-2^31 ~ (2^31 - 1)

-128~127

long

Long

-2^63 ~ (2^63 - 1)

-128~127

float

Float

--

double

Double

--

boolean

Boolean

true、false

true、false

char

Character

\u0000 ~ \uffff

\u0000 ~ \uffff

Java博大精深,要想深入,基础必须要好,才能避免bug。

我们程序员的职责就是少写bug,这才是我们一直学习的动力。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值