- 此问题在此处已有答案**:
Compare two objects with .equals() and == operator(16个答案)
昨天关门了。
所以我在java上有这个方法
public Discussion publishDiscussion(String title, String body, Long courseId, Long userId)
{
Course course = courseService.findCourseById(courseId);
if (course == null || course.getProfId() != userId)
{
if (course==null)
{
System.out.println("subject is null");
}
if(course.getProfId() != userId)
{
System.out.println("prof id "+course.getProfId()+" does not match with "+userId);
}
return null;
}
Discussion discussion = new Discussion();
discussion.setTitle(title);
discussion.setBody(body);
return discussionRepo.save(discussion);
}
当参数userId = 352并且course不为空时,它不会保存到数据库,而是返回null。我检查了它,似乎userId和course的prof id之间的相等性不相等,因为它进入了if语句(course. getProfId()!= userId),而且它会打印
prof id 352与352不匹配,我想知道为什么这两个不相等,如果它都显示352
跳过if语句以保存实体讨论
2条答案
按热度按时间ia2d9nvy1#
你可以用
==
操作符比较原语(long
),但是在对象的情况下(Long
是一个Object),它比较对象的引用。因为变量不指向同一个对象,所以返回false。为了比较两个对象,正如注解中提到的,需要使用
.equals()
方法。ecfsfe2w2#
您使用的
Long
不正确;可能您认为Long
和long
是相同的(它们不是),或者您知道它们的意思不同,但不太清楚它们是如何表示的,并且Long
对您来说看起来更好。别再那样做了
Long
和你想的完全不一样。这两个变量之间的关键区别在于
Long
是一个对象,因此Long
类型的所有变量都是references,它们就像地址簿中的一页,解释了在哪里可以找到实际值。而且,像所有的引用一样,
==
不是你认为是的运算符。==
,如果左边和右边都是引用,检查 * 引用同一性 * -换句话说,给定一个巨大的草地,上面有带数字的postit注解,a == b
,其中a
和b
是Long
,检查地址(这个巨大字段中的坐标)是否相同。在这里,它们并不相同-但如果你走到a
和b
字段中的注解处,你会发现虽然它们是单独的注解,但它们上打印的值相同。要测试这种意义上的相等性,可以使用
a.equals(b)
,它尽职尽责地“遍历”(解引用)注解,并检查它们的 * 值 * 是否相等。但是,这主要是真的混淆这里-停止使用
Long
。相比之下,
long
是一个基元,值是 * 直接 * 存储在变量中的,对于a == b
,其中a
和b
都是基元,这是一个直接的值比较(这些不是引用,在这里谈论“引用标识”甚至没有开始)。有点复杂的是java语言中的自动取消装箱规则:如果你对一个“primitive wrapper”类型的引用执行一个操作(比如
Long
,Short
,Double
等--大写),这是一个编译时错误,因为你不能对引用执行操作,只能对原语执行操作,java会默认你想对值执行那个操作,并注入unbox代码。换句话说,同时:
因为
==
对于引用有意义,但是<
没有,所以java把最后一行转换成if (!(a.longValue() < b.longValue()) ....
)--特别是如果a或b为空,则包括生成NullPointerException
的那一行。简单的解决方案:不要使用
Long
、Integer
等,直到你完全理解了什么是引用,并且真正知道你在做什么。