Object类的clone/equals/toString常用方法详解
来源:互联网 发布:印度现状 知乎 编辑:程序博客网 时间:2024/05/17 18:11
Object类是所有Java类的祖先。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
一、clone方法
这几天在看接口的这一章,在Comparable接口中看到了一个不知道怎么解释的问题:Object类是所有类的父类,为什么实现Comparable接口的子类一定要重写Object类用protected修饰的的clone方法而不能直接使用?
看了好几遍都不知道是什么原因,写程序试一下发现确实是这样。若没有重新,在主类中调用实现Comparable接口的类的对象的clone()时编译报错:The method clone() from the type Object is not visible。网上查才发现原来是我对protected的认识存在误区——搞混了作用范围。
接下来就来分析一下clone方法重写的必要性以及如何进行深拷贝:
以下面程序段为例:(为了方便数据域都设置为public)
class House implements Cloneable {public java.util.Date date;public String id;public int area;public House(String id,int area) {this.date=new java.util.Date();this.id=id;this.area=area;}public Object clone() throws CloneNotSupportedException{super.clone();String id;int area;java.util.Date date=new java.util.Date();id=this.id;area=this.area;date.setTime(this.date.getTime());return new House(id,area);}}public class Test { public static void main(String[] args) throws CloneNotSupportedException { House h1=new House("1",5);House h2=(House)h1.clone();System.out.println(h1==h2);System.out.println(h1.id==h2.id);//true 因为限定字符串System.out.println(h1.date==h2.date);//false 深复制了,指向不同Date对象System.out.println(h1.date.toString());System.out.println(h2.date.toString());//结果和上一句相等 }}
上面代码值得一提的是,这一个深拷贝的例子。其中System.out.println(h1.id==h2.id);的结果是true ,因为限定字符串的原因(String的内容相同则指向同一个对象);而System.out.println(h1.date==h2.date);的结果是false,是因为已经进行深复制了,此时两个date是指向不同Date对象。
回到正题,这里必须强调protected的保护规则:
修饰符为protected的方法在同包中与public的作用范围相同(Object类的包是java.lang)。
但在不同包中,子类只能在自己的作用范围内访问自己继承的父类protected域(如任何类都可直接访问Object的clone方法),但无法访问到别的类继承的protected域。例如,在主类Test中无法访问House类继承的clone方法(即不可在Test的main方法中使用h1.clone(),但Test的对象可以使用t.clone()))。
因此我们要继承后修改可见性为public,使在Test类的作用范围内可访问House对象的clone方法。
注:clone方法被覆盖之后相当于是子类自己定义的方法,同一包的其他类可见 。
二、equals方法
先上一段源代码:
public boolean equals(Object obj) { return this == obj; }这是equals方法在Object类中的实现。可以看到,该方法相当于==,即判断调用equals的对象和形参obj所引用的对象是否是同一对象。要注意:即便是内容完全相等的两块不同的内存对象,也返回false。
然而看了书上的例子:
java.util.Date date1=new java.util.Date();java.util.Date date2=(java.util.Date)date1.clone();System.out.println(date1==date2);//falseSystem.out.println(date1.equals(date2));//true结果是一个false一个true,理由是二者是内容相同的不同对象。但这和上面的实现方法相矛盾。
疑惑时突然发现是因为我忽略掉了一点——Date类中已重写了equals方法!此外,java中大部分类也都重写过equals方法。
这样就可以解释,为什么自己写的类若没有覆盖equals方法就直接使用得到的结果是和==一样,但使用java中已有的类的equals方法就是判断二者的内容是否相等了。
因此,如果希望在不同内存但相同内容的两个对象使用equals方法时返回true,需要重写父类的equals方法。
三、toString方法
以前一直没有注意这个方法,是在涉及到接口和抽象类时才好好理解了一下。
首先,使用System.out.print(obj)可以打印出对象obj的字符串表示,运行时JVM会自动调用toString方法,即相当于System.out.print(obj.toString())。
而默认的toString方法获得的字符串由类名+标记符@+此对象哈希码的无符号十六进制表示组成。所以,在自定义的类中一般也会重写该方法,以获得我们真正需要的信息。
四、其他方法
除了上面四个常用方法,Object类中还有其他方法,由于目前不经常使用,在此仅列出而不赘述:
finalize() :当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
getClass():返回一个对象的运行时类。
hashCode() :返回该对象的哈希码值。
notify() :唤醒在此对象监视器上等待的单个线程。
notifyAll() :唤醒在此对象监视器上等待的所有线程。
wait() :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
wait(long timeout, int nanos) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
getClass():返回一个对象的运行时类。
hashCode() :返回该对象的哈希码值。
notify() :唤醒在此对象监视器上等待的单个线程。
notifyAll() :唤醒在此对象监视器上等待的所有线程。
wait() :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
wait(long timeout) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量。
wait(long timeout, int nanos) :导致当前的线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者其他某个线程中断当前线程,或者已超过某个实际时间量。
阅读全文
0 0
- Object类的clone/equals/toString常用方法详解
- Object类的toString()和equals()方法
- Object的方法equals,hashCode,toString,clone。另外Comparable接口的方法
- 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解
- Object(equals,finalize,clone,hashCode,toString),与包的重名
- Java:object类 中常用equals()和 toString()方法的重写
- Object的equals方法和toString方法
- Object类中equals,hashCode和toString方法的学习
- 覆盖Object类的equals、hashCode和toString方法
- Object类中的toString(),equals(), hashCode()方法之间的关系
- 复写Object超类的equals,hashCode,toString方法
- Object 类中 equals和toString() 方法
- Object 类中 equals和toString() 方法
- Object类与 toString , equals方法
- Object常用方法介绍及注意事项equals(),hashCode(),getClass(),toString()
- Object 开发中常用的重写方法总结toString,equals,hashCode,compareTo
- Object 开发中常用的重写方法总结toString,equals,hashCode,compareTo
- 详解Object类的equals方法
- gitlab 安装报错无法重启nginx
- 获取url参数方法
- vs2013平台,C#使用mysql,安装mysql-connector-net-6.9.9-noinstall
- 邮件传输协议 SMTP 、POP3 、IMAP 和 Exchange 比较及联系?
- 系统的MVP购物车(二级购物车全)
- Object类的clone/equals/toString常用方法详解
- Linux下如何关闭防火墙,如何查看防火墙当前的状态
- ssh: Could not resolve hostname guard.: Name or service not known
- 输入框进行判断验证(弹出对话框,点击按钮查询并隐藏)
- Mysql读写分离
- echarts --流程图模型
- 如何转载别人文章(vyeah)
- Java基础总结第(6)天
- 并发设计模式之生产者-消费者模式