让我们首先考虑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
块中的唯一语句不会执行,与前面的语句相反。怎么样?
答案 0 :(得分:36)
您正在将Long
与int
进行比较。 java.lang.Long#equals
的javadoc表示equals
方法
将此对象与指定对象进行比较。当且仅当参数不为null并且是包含与此对象相同的long值的Long对象时,结果才为真。
而是尝试System.out.println(new Long(1).equals(1L));
现在,您要将Long
与Long
而不是Long
与Integer
进行比较,它会打印{{ 1}}。
答案 1 :(得分:6)
字面值1
不 a long
,它是int
。请尝试使用以上代码:
System.out.println(temp1.equals(1L));
和
if (temp1.equals(1L))
正如您所看到的,在文字值L
之后加1
表示它是long
,然后比较按预期工作。
答案 2 :(得分:6)
您可以进行比较的原因是因为Java中的自动装箱。
您调用的实际方法是:
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Long.html#equals(java.lang.Object)
将您的Long对象与其他Object进行比较,而不是与实际的原始int进行比较。
调用该方法时会发生的事情是您的原始integer(1)
被自动装箱到Object(Integer)
,因此您实际上正在调用:
new Long(1).equals(new Integer(1));
这就是它失败的原因。
这就是为什么你打电话
new Long(1).equals(1L)
这样可行,因为Java会将1L
(原始long
,而不是int
)自动装入Long
对象,而不是Integer
对象。
答案 3 :(得分:3)
根据Javadoc's page on Long
,.equals
method仅在true
评估为<{p}}
Long
对象Long
个对象必须具有相等的值在您的方案中,1
是int
,而不是Long
对象,因此失败(1),因此评估为false。如果您需要测试long
,请改用1L
。
答案 4 :(得分:3)
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(和不等于)。虽然如果你知道你只是渴望获得多头和生命,那么生活就会更简单,因为你可以做到以下几点。
Number n0 = new Long(1L);
Number n1 = new Integer(1);
boolean equal = n0.longValue() == n1.longValue();
答案 5 :(得分:2)
这种行为与自动装箱一致,将1
转换为Integer
,然后将Integer(1)
与另一个Long
进行比较。将Integer
与false
进行比较会产生1L
。
如果您使用Long
与true
进行比较,则会产生{{1}}。
答案 6 :(得分:2)
此代码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}来更正} ,,,例如1
,通过这样做,我们将temp1.equals(1L)
对象与Long
进行比较,并将结果设为TRUE
答案 7 :(得分:1)
public boolean equals(Object obj) {
if (obj instanceof Long) {
return value == ((Long)obj).longValue();
}
return false;
}
答案 8 :(得分:1)
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,那么第一次检查将失败,因此您将得到错误的结果。
答案 9 :(得分:0)
您可以在不使用equals()的情况下比较长整数值。只有在我比较字符串时才需要这样做。