【JAVADYA22】Java,哈希码以及equals和==的区别,java为什么要有接口?

从开始学习Java,哈希码以及equals和’= = ‘的区别就一直困扰着我。
要想明白equals和’= =‘的区别首先应该了解什么是哈希码,因为在jdk的类库中不管是object实现的equals()方法还是String重写的equals()方法以及其它基本数据类型的包装类重写的euqals()方法,他们在比较对象的时候都是根据hashCode()方法返回的哈希码来判断两个对象是否相等的,所以要想搞清楚equals()就必须要知道什么是哈希码。
那么究竟是什么哈希码呢?哈希码是可以根据的自己的需求,采用不同的算法产生的一个Int型数字。Object的hashCode()方法返回的哈希码是根据对象的内存地址来生成的,所以每个对象的哈希码是不相同的,如果你要比较的两个变量的类型没有重写Object的hashCode()方法那么这两个变量除非是指向相同的对象(地址相同),否则返回的一定是false。而String以及基本数据类型的包装类中都重写了hashCode()方法,他们生成的哈希码是跟他们的内容(这里就是指值)息息相关,也就是说在用equals()比较两个变量是否相等的时候只要他们的值相等,那么就返回true,因为他们生成的哈希码相等。有个值得注意的地方是:在JDK的类中只要重写的Object的equals()方法,那就肯定重写了它的hashCode()方法,因为equals()方法中在比较两个变量时,判断的标准就是哈希码是否一样,Object中的hashCode()方法是根据对象的内存地址生成的,如果重写了equals()方法而继续使用原来的hashCode()方法生成的哈希码作为判断相等的依据,那显然达不到我们要改变判断对象是否相等的标准的效果。
既然知道了什么是哈希码,现在就可以说明equals()和’= =‘的区别了,对于没用重写Object的equals()方法的类型所生成的对象的比较,equals()和’= =‘是效果一样的,’= =‘比较的是两个变量所指向的对象在内存中指向的地址是否一样,而当两个变量的类型中继承了Object的equals()方法的时候,由于该方法比较的标准是看哈希码是否相等,而哈希码是由hashCode()方法生成的,该方法生成哈希码的依据是对象在内存中的地址,最终比较的还是地址。所以说equals()和’= =‘效果一样。而对于像String和那些基本数据类型的包装类来说equals()和’= =‘就不一样了,因为他们重写了Object的equals()方法和hashCode()方法,使得equals()方法的判断标准发生了改变,他们的判断标准是看对象的内容是否相等,这里就是指值是不是一样,因为他们的哈希码是根据对象的值生成的,与内存地址无关了,所以他们的equals()方法比较的是对象的值是否相等,而’= =‘比较的仍然是地址。所以equals()和’= =‘就不一样了。
这里还要注意一下,在比较值的时候,一般’= =‘比较的是基本数据类型,而equals()比较的是引用数据类型,地址相同一定值相等,而值相等地址不一定相同。如果比较的是地址,那最好是用’= =’,因为无论是否重写了Object的equals()方法,’= ='永远比较的是地址,equals()比较的是哈希码,而哈希码生成的标准是由类作者自己根据需求来控制的。

为什么要引用接口?

- 1.接口不是类,为什么?
  接口如果是类,那就失去了java引入接口的意义了。
  java之所以引入接口,就是为了弥补不能多继承的缺点,在java中每个类只能有一个超类,但却可以实现多个接口。
2.接口可以有静态常量(一定是静态的,无论写没写static),但是不能含有实例域,为什么?
  接口就类似一个说明文档,定义继承接口的类应该必须有什么方法以及该方法的输入输出。
  接口的思想不允许出现变量,接口只是对一类事物的属性和行为更高层次的抽象。对修改关闭,对扩展(不同的实现 implements)开放。所以接口中的属性必然是常量,只能读不能改,这样才能为实现接口的对象提供一个统一的属性。
3.接口中可以有静态方法,为什么?
  JAVA SE 8中可以定义带有方法体的静态方法,以保证“源代码兼容”。
4.接口可以有静态常量,并且这个常量一定是静态的,为什么?
  因为static是所有对象可以访问,而且可以直接通过类名访问。接口没有对象,必须通过类名来访问所以是要静态的。
5.内部接口默认是静态的,为什么?
  接口不能被实例化,所以内部接口只有在静态时才有意义。 因此,默认情况下,无论是否手动添加静态,内部接口都是静态的。
想清楚这些,再想想接口和抽象类有什么不一样,什么时候用接口,什么时候用抽象类?
  1.抽象类是类,但接口不是。
  2.接口中的方法都是抽象方法,而抽象类必须有抽象方法,但也可以有普通方法。
  3.接口定义的方法以及常量都是public,而抽象类是可以有私有方法或私有变量的。
  4.实现接口需要实现接口中的每一个方法,而继承抽象类则可以选择实现抽象类中的一部分抽象方法,但此时这个子类仍然是一个抽象类。
  5.接口可以实现多继承,但是一个类只能实现一个超类。
  6.接口中定义的变量默认是public static final 型,必须给其初值,所以实现类中不能重新定义,也不能改变其值。抽象类中的变量默认是default 型,其值可以在子类中重新定义,也可以重新赋值。
  接口更像是一种协议,实现接口的子类需要按照这种协议来编写自己的代码,但抽象类就更像一个不能实例化的普通类,只不过为了子类更加灵活多变,将一部分方法留给子类去实现,这也体现了java的多态。
  - 总结:为了规范,预防冗余,以及别的程序员看不懂代码。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Keyle777

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值