比较非基元Long值127和128

我想使用if条件来比较两个Long对象的值。 当这些值小于128时if条件正常工作,但是当它们大于或等于128时 ,比较失败。

例:

 Long num1 = 127; Long num2 = 127; if (num1 == num2) { // Works ok } 

上面的代码比较正常工作,但在下面的代码失败:

 Long num1 = 128; Long num2 = 128; if (num1 == num2) { // Does NOT work } 

为什么比较variables与大于127的值有问题? 如果variables数据types改变为长基元 ,那么比较适用于所有情况。

为什么在比较大于127的Longvariables时存在问题? 如果上面的variables的数据types是原始的(长),那么代码适用于所有的值。

Java高速caching范围从-128到127的整数对象实例 。 那就是说:

  • 如果您设置N长variables的值为127caching ),则所有引用都会指向同一个对象实例。 (N个variables,1个实例)
  • 如果您设置N长variables值128不caching ),您将有一个对象实例指向每个引用。 (N个variables,N个实例)

这就是为什么这个:

 Long val1 = 127L; Long val2 = 127L; System.out.println(val1 == val2); Long val3 = 128L; Long val4 = 128L; System.out.println(val3 == val4); 

输出这个:

真正

对于127L值,由于两个引用(val1和val2)指向内存中相同的对象实例(caching),它将返回true

另一方面,对于128值,由于没有实例将其caching在内存中,因此为盒装值的任何新赋值创build一个新实例,从而产生两个不同的实例(由val3和val4指向)并返回false他们之间的比较。

发生这种情况的唯一原因是您将两个Long 对象引用 (不是long原始值)与==运算符进行比较。 如果不是这个Cache机制,这些比较总是会失败,所以真正的问题在于比较box操作符和==操作符。

将这些variables更改为原始longtypes将防止这种情况发生,但是如果您需要使用Long对象保留代码,则可以使用以下方法安全地进行这些比较:

 System.out.println(val3.equals(val4)); // true System.out.println(val3.longValue() == val4.longValue()); // true System.out.println((long)val3 == (long)val4); // true 

国际海事组织 ,在处理对象比较时坚持使用.equals()方法总是一个好主意。

免责声明:如果这些值中的任何一个为空(即使长到会抛出exception),大多数比较都会失败,所以需要额外的检查来适应这些情况。

参考链接:

num1num2是长对象。 你应该使用equals()来比较它们。 ==比较可能有时会因为JVM框元素的方式而起作用,但不依赖于它。

 if (num1.equals(num1)) { //code } 

Java将原始值从-128caching到127 。 当我们比较两个对象java内部types转换为原始值并比较它。 但在127以上的龙对象不会得到types种姓。 Java通过.valueOf()方法caching输出。

此caching适用于从-128到127的Byte,Short,Long。对于Integercaching工作,从-128到java.lang.Integer.IntegerCache.high或127,取其中较大者(我们可以将顶层值设置为最大值应该通过使用java.lang.Integer.IntegerCache.highcaching)。

  For example: If we set java.lang.Integer.IntegerCache.high=500; then values from -128 to 500 will get cached and Integer a=498; Integer b=499; System.out.println(a==b) Output will be "true". 

Float和Double对象永远不会被caching。

字符将从0到127caching

你正在比较两个对象。 所以==运算符将检查对象引用的相等性。 有以下几种方法来做到这一点。

1)types将这两个对象转换为原始值并进行比较

  (long)val3 == (long)val4 

2)读取对象的值并进行比较

  val3.longValue() == val4.longValue() 

3)在对象比较上使用equals()方法。

  val3.equals(val4); 

比较Java中的非基元(又名对象)和==比较它们的引用而不是它们的值。 Long是一个类,因此Long值是对象。

问题在于,Java开发人员希望人们使用Long来提供兼容性,这就导致了自动装箱的概念,这就是本质上的特点,即Long value会根据需要变成Long Objects,反之亦然。 虽然自动装箱的行为并不是一直可以预测的,但是还没有完全确定。

所以为了安全起见,要有可预见的结果,在这种情况下总是使用.equals()来比较对象,而不要依靠自动装箱。

 Long num1 = 127, num2 = 127; if(num1.equals(num2)) { iWillBeExecutedAlways(); }