本篇介绍在对对象进行比较和克隆操作的时候会使用的接口,然后介绍一个类:Object
在Java中Object类默认是所有类的父类,里面有一些常用的方法会介绍
1.对象的比较
两个对象要进行比较之前,我们首先需要确定依据什么来进行比较,对象中的成员变量那么多,直接比较是无法比较的
1.1 Comparable
此接口里面只有一个compareTo抽象方法,结构如下:
在类中实现此接口后就可以进行类和类之间的大小的比较
1.2 Comparator
这个接口中有一个抽象方法compare,同样是用来实现对象之间比较大小,方法的结构如下:
和Comparable
如果是元素为类的数组,使用Comparator
2.克隆对象
2.1 Cloneable
这个接口是一个空接口,但类需要实现此接口才能被克隆,而要重写的方法则是Object类中的clone()方法
在IDEA中自动重写的clone()方法如下:
throws以及后面的语句不是现在的重点,暂时略过
因为此方法的返回值是Object类,所以在使用的时候记得结果强制类型转换成子类
2.2 深拷贝和浅拷贝
既然说到克隆,那就不得不提深拷贝和浅拷贝,简单说下二者的概念:
假设将A的内容拷贝到B中,然后我们修改B中的内容,如果A的内容没有改变,那么就是深拷贝,否则就是浅拷贝
需要说明的是:一个克隆方法是深拷贝还是浅拷贝和类里面的成员变量以及自己写的代码都有关系,两个不同的类使用同一个克隆方法,一个是深拷贝,另一个是浅拷贝,这种情况是存在的
现在有一个类如下:
class A implements Cloneable{ int i; int j; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "{" + "i=" + i + ", j=" + j + '}'; } }
我们在main方法中将其实例化后克隆给另一个对象,看看结果:
此时a并没有因为b的改变而改变,clone()为深拷贝
我们再将类A进行改造:
class B implements Cloneable { int k; } class A implements Cloneable{ int i; int j; B c=new B(); @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { return "{" + "i=" + i + ", j=" + j + ", c.k=" + c.k + '}'; } }
结果如下:
那么此时clone是深拷贝还是浅拷贝?
出现这种结果的原因要从内存上看,在类A没有进行修改之前内存如下:
类A修改后的内存如下:
按照上图来看,要实现深拷贝就需要把类B的内容再克隆一份,所以我们需要对clone方法进行修改
class B implements Cloneable { int k; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } class A implements Cloneable{ int i; int j; B c=new B(); @Override protected Object clone() throws CloneNotSupportedException { A tmp=(A)super.clone(); tmp.c=(B)this.c.clone(); return tmp; } @Override public String toString() { return "{" + "i=" + i + ", j=" + j + ", c.k=" + c.k + '}'; } }
至于为什么自己画图试试 ,这里就不讲了
3.Object类
Object类中有一些常用的方法这里拿出来介绍
3.1 equals
在Object类中此方法是用来比较大小的,返回值是布尔值,底层的实现逻辑如下:
public boolean equals(Object obj) { return (this == obj); }
关于“==”,如果两边的变量是基本类型的变量,比较的是值是否相同,而如果是引用类型的变量的话,比较的则是地址是否相同
3.2 toString
输出语句System.out.println()底层调用的就是toString方法,不过如果输出的是引用类型数据默认是输出修改后的地址,所以此时需要对其进行重写,这也是上面的例子中有toString方法的原因
本篇结束,完
到此这篇关于Java由浅入深通关抽象类与接口下的文章就介绍到这了,更多相关Java抽象类与接口内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!