Java中的equals()方法在Long数据类型上意外地工作
我们首先考虑Java中的以下表达式。
Integer temp = new Integer(1); System.out.println(temp.equals(1)); if(temp.equals(1)) { System.out.println("The if block executed."); }
这些所有陈述都很好。 毫无疑问。 表达式temp.equals(1)
按预期计算为true
,因此if
块中的唯一语句将被执行。
现在,当我将数据类型从Integer
更改为Long
,语句temp1.equals(1)
意外地评估为false
,如下所示。
Long temp1 = new Long(1); System.out.println(temp1.equals(1)); if(temp1.equals(1)) { System.out.println("The if block executed."); }
这些是前面片段中提到的等价语句,只是数据类型已经改变,它们的行为正好相反。
表达式temp1.equals(1)
被计算为false
,因此, if
块中的唯一语句不会执行与前面语句相反的语句。 怎么样?
你将Long
与int
进行比较。 java.lang.Long#equals
的javadoc表示equals
方法
将此对象与指定的对象进行比较。 当且仅当参数不为null并且是包含与此对象相同的long值的Long对象时,结果才为真。
而是尝试System.out.println(new Long(1).equals(1L));
现在你要比较Long
to a Long
而不是Long
to Integer
,它将打印为true
。
字面值1
不 long
,它是一个int
。 请尝试使用以上代码:
System.out.println(temp1.equals(1L));
和
if (temp1.equals(1L))
如您所见,在字面值1
之后放置一个L
表示它很long
,然后比较按预期工作。
您可以进行比较的原因是因为Java中的自动装箱。
您调用的实际方法是:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Long.html#equals(java.lang.Object )
这是将您的Long对象与其他对象进行比较,而不是与实际的原始int进行比较。
调用该方法时会发生的情况是您的原始integer(1)
被自动装箱到一个Object(Integer)
因此您实际上正在调用:
new Long(1).equals(new Integer(1));
这就是它失败的原因。
这就是你打电话的原因
new Long(1).equals(1L)
这样可以工作,因为Java会将1L
(原始long
,而不是int
)自动装箱到Long
对象中,而不是Integer
对象。
根据Javadoc在Long
上的页面 , .equals
方法只有在得到时.equals
计算为true
- 参数是一个
Long
对象 - 如果(1)为真,则
Long
对象必须具有相等的值
在您的方案中, 1
是int
,而不是Long
对象,因此它失败(1),因此计算结果为false。 如果您需要long
测试,请改用1L
。
Java很懒惰。
当您执行以下比较时,java会自动将int转换为long(因为long可以包含int可以包含的任何值)。 比较是在两个多头而不是两个整数之间。
int i = 1; long l = 1L; boolean b = i == l;
Java能够这样做,因为有关i
和l
的类型信息在编译时和执行比较时是已知的。 但是,当您使用盒装版本时,可以在编译时知道类型,但在执行比较时则不知道 。 这是因为比较必须在equals方法中完成,并且由于equals将Object作为参数,因此类型信息会丢失。 因此,Java是懒惰的,只检查两个盒装数字是否相等,如果它们都是相同Number类的实例(例如,Integer,或者都是Long,或者两者都是Double等等)。
原来唯一完全可靠的方法是在运行时比较两个未知类型的数字,将两者都转换为字符串,然后转换为BigDecimal,然后使用方法compareTo(而不是 equals)。 虽然如果你知道你只是渴望获得多头和生命,那么生活就会变得更简单,因为你可以做到以下几点。
Number n0 = new Long(1L); Number n1 = new Integer(1); boolean equal = n0.longValue() == n1.longValue();
该行为与自动装箱一致,将1
转换为Integer
,然后将其与另一个Integer(1)
进行比较。 将Long
转换为Integer
产生false
。
如果你使用1L
来比较Long
那么它将产生true
。
Long temp1 = new Long(1); 的System.out.println(temp1.equals(1));
if(temp1.equals(1)){System.out.println(“if块执行。”); }
在这段代码中, temp1.equals(1)
将Long
对象与Integer
对象进行比较,得到结果为false,我们可以通过使用1L
而不是1
来纠正它,例如temp1.equals(1L)
,通过这样做,我们进行比较Long
对象,结果为TRUE
类Long的equals()
方法的实现说明了原因:
public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; }
Java.lang.Long中的equals方法最初仅在比较值之后才以instanceOf Long检查开始。
public boolean equals(Object obj) { if (obj instanceof Long) { return value == ((Long)obj).longValue(); } return false; }
因此,如果您要在Long值的位置使用Integer Value,那么第一次检查将失败,因此您将得到错误的结果。
您可以在不使用equals()的情况下比较长整数值。 只有在我比较字符串时才需要这样做。