关于本节课的equlas方法思考

关于本节课的equlas方法思考

看了Objects的源码,equals返回的是引用地址的相等是否,这里没有用String的equals

http://img1.sycdn.imooc.com//climg/5beb82b80001f55608940328.jpg

http://img1.sycdn.imooc.com//climg/5beb82c5000165e808940160.jpg

如图所示,java不会给直接等号赋值的字符串额外分配一个内存,而給new方法新建的相同字符串重新分配一个内存值,也就是这里的req.getServletPath是返回的同一个字符串?

http://img1.sycdn.imooc.com//climg/5beb839800016d0804320047.jpg

由于这里的HttpRequestServlet是一个接口,我看不到里面的具体实现,所以我只能猜测这个方法只是简单的返回了一个字符串引用,那么问题是:


调用Objects.equals("/cart/list.do",req.getServletPath())方法,应该是新建了一个"/cart/list.do"String对象,他应该是新分配的内存空间才对,怎么会和req.getServletPath()相等?

正在回答

登陆购买课程后可参与讨论,去登陆

5回答

Object中的两个参数的equals方法也不是比较的地址值。楼上的老师提供过Object中的两个参数的equals方法的源码

http://img1.sycdn.imooc.com//climg/5beccd27000157cb05890097.jpg

同学可以解读一下

如果“/cart/list.do”和req.getServletPath() 完全相等包括地址值的话,那个肯定 a==b 就是true了。

那如果他们地址值不相同,但是是一样的字符串呢?它就是去执行||后边的判断

只要a不是null,他就会去调用字符串的equals方法,既然同学理解字符串的equals方法,那同学肯定能理解下边的这个判断。

http://img1.sycdn.imooc.com//climg/5beccdc50001045a02670041.jpg

“/cart/list.do”.equals(req.getServletPath())

他们也会返回true。

|| 符合,只要有一个是true,返回值就会是true。


如果我的回答解决了你的疑惑,请采纳!祝学习愉快!


  • 楚楚提 提问者 #1
    感谢回复,明白了,我忽略了重写的equals,看源码时理解成了object的自带equals方法,另外延伸问一下,就是如果req.getserverpath中,他要返回的那个字符串,如果是直接用等号拼接起来的,那他的地址值和前面的那个cart/cart.do字符串相等吗
    2018-11-15 10:09:46
  • 好帮手慕阿莹 回复 提问者 楚楚提 #2
    同学可以自己写一个类,然后里边写个用==比较的方法,比较的时候调用这个方法试一下就可以喽。 如果我的回答解决了你的疑惑,请采纳!祝学习愉快!
    2018-11-15 10:26:44
好帮手慕阿莹 2018-11-14 20:02:01

额,同学是把equals和==搞混了。==是比较地址值的。但是String中equals重写了,它不比较地址值:这里我写了个案例:

package File;
public class HelloWorld {
	public static void main(String[] args) {
		String a = "HelloWorld";
		String b = "HelloWorld";
		String c = new String ("HelloWorld");
		//用==比较
		System.out.println("用==比较比较a和b:  "+(a==b));
		System.out.println("用==比较比较a和c: "+(a==c));
		//用equals比较
		System.out.println("====================================");
		System.out.println("用equals比较a和b :"+(a.equals(b)));
		System.out.println("用equals比较a和c : "+(a.equals(c)));
	}
}

运行结果如下

http://img1.sycdn.imooc.com//climg/5bec0e32000102fd04300162.jpg

同学可以通过案例看到 ,String中重写的equals方法是不在乎地址值的。

Objects.equals("/cart/list.do",req.getServletPath())方法 和String中的这个是一个道理的。

如果我的回答解决了你的疑惑,请采纳!祝学习愉快!

  • 提问者 楚楚提 #1
    我没搞混,这个我知道,我想问的req.getserverpath的实现过程是怎样的,才保证他们具有相同的地址值,也就是他不是new出来的对象
    2018-11-14 20:06:21
  • 好帮手慕阿莹 回复 提问者 楚楚提 #2
    同学你可以再看一下这个例子,重新new出来的对象,只要一样,地址值不同它也是true,你看看a 和c 的比较。a和 c 的地址值是不同的,但是他们用equals就是返回true。这里没有保证他们具有相同的地址值。祝学习愉快。
    2018-11-15 09:27:17
  • 提问者 楚楚提 回复 好帮手慕阿莹 #3
    我说的equals不是string,如果是string,就不问了,我是说objects当中的equals,他比较的是地址值,问题核心在于req.getserverpath返回的地址值怎么就和新建的字符串相等了
    2018-11-15 09:32:23
一叶知秋519 2018-11-14 19:38:14

同学可以通过这张图来理解一下同学提到的问题:

str1声明的imooc会进入常量池,当常量池中存在一个imooc后,再进行字符串str2声明时,就会指向常量池的imooc,不会再重新定义一个新的imooc,所以实际上str1和str2的地址是相同的,是同一个内容;

而通过new创建的字符串对象会进入堆中,如果在通过new创建一个字符串对象,会再开辟一块新的空间,这也是字符串的特殊性。String普通声明会进入常量池,创建对象会开辟空间进入堆中。

http://img1.sycdn.imooc.com//climg/5bec07d00001cc3711800787.jpg

在进行字符串声明时,如果没有创建对象的过程,就会直接指向常量池,在常量池中进行寻找。

这些内容在《Java零基础》课程中涉及到了,同学如果感兴趣的话,可以学习一下《Java零基础》课程: https://class.imooc.com/sc/18 

如果解决了你的疑惑,请采纳,祝学习愉快!

  • 提问者 楚楚提 #1
    感谢回复,您说的这个我自学的时候已经知道了,我想问的就是,equals方法能得到true,应该就是进入您说的常量池了,所以我在乎的就是req.getserverpath这个方法是怎么进入常量池的
    2018-11-14 19:41:21
一叶知秋519 2018-11-14 18:02:26

首先Objects类中equals()方法的源码是这样的:
http://img1.sycdn.imooc.com//climg/5bebeca500010afb05900096.jpg

也就是说,a和b的地址相同 或者 a在不为空的情况下,a的值和b的值相同,都会返回true。

当传入的a和b如果是字符串,那么a.equals(b)调用的就是String类中的equals()方法。

String类的equals()方法比较的内容,而不是地址。

同学所提到的问题是:

Objects.equals("/cart/cart.do",req.getServletPath()) 这句代码中a位和b位的地址是否相同?

这个地方可以看做是两个常量在进行比较,因为没有创建对象的过程,所以可以看做字符串常量;

常量在比较的时候就是比较的内容了,和地址没有关系的。

如果解决了你的疑惑,请采纳,祝学习愉快!

  • 提问者 楚楚提 #1
    老师按照你的这种思维方式确实能把问题想通,但是我觉得并没有洞悉这个问题的本质,我觉得还是那张图,就是我上传的第一张,做java测试那里,说明了相同字符串不再重新分配内存地址,所以这里我认为应该是不再重新分配内存,equals里面的两个对象地址是同一个,所以返回true
    2018-11-14 18:56:55
一叶知秋519 2018-11-14 13:53:42

String类的equals()方法比较的是值,并不是地址;

这个地方是使用的Objects类的equals(a,b)方法,在a和b不为空的情况下,只要a和b的值相同就会返回true。

祝学习愉快!

  • 提问者 楚楚提 #1
    这个我知道,我说的就是为什么他们是同一个内存地址
    2018-11-14 15:39:00
  • 提问者 楚楚提 #2
    是不是因为Objects.equals("/cart/cart.do",req.getServletPath())中 req.getServletPath()在返回字符串的时候,系统创建了一个匿名对象,而 "/cart/cart.do" 这个字符串的值和匿名对象因为是相等的字符串,所以系统并没有給他分配一个内存地址,所以他两相等了
    2018-11-14 15:55:10
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
从网页搭建入门Java Web2018版
  • 参与学习           人
  • 提交作业       1088    份
  • 解答问题       10205    个

如果你有Java语言基础,又想以后从事Java Web开发,那么本路径是你的不二选择!本路径从网页搭建开始入手,通过大量案例来学习Java Web基础。定能助你完成Java Web小白的蜕变!

了解课程
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师