关于Object里面需要重写的方法以及细节
P527-P539
关键词:toString equals finalize Object
关于Object类的toString()方法的源码
1.源码长什么样子
public String toString(){
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
}
源码上toString方法的默认实现是:
类名@对象的内存地址转换成十六进制的形式
2 .SUN公司的这样设计的目的是什么
通过调用这个方法可以将一个 java对象转换成字符串形式
3.SUN公司开发java语言时,建议所有子类都去重写toString()方法
toString()方法应该是一个简洁的,详实的,易阅读的。
输出引用的时候,会自动调用toString()方法
关于Object类中的equals方法
1.equals方法的源代码
public boolean equals(Object obj) {
return (this == obj);
}
以上这个方法是Object类的默认实现。
2.SUN公司设计equals方法的目的是什么?
以后编程过程中,都要通过equals方法来判断两个对象是否相等,equals方法是判断两个对象是否相等的。
3.我们需要研究一下Object类给的这个默认的equals方法够不够用
在Object类中,无法判断两个两个对象是否相等,因此我们要自行重写equals方法,让他能判断对象的内容是否相等。
4.判断两个对象是否相等,不能用==
因为==比较的是两个对象的内存地址
5.java.lang下的String方法也是重写了equals和toString方法的。
会比较对象的内容,以及输出引用的使用,也是输出他的本身内容
大结论:
java中的什么数据类型可以使用“==”来判断
java中的基本类型比较是否相等,使用==
java中的什么类型数据需要使用equals判断
java中所有的引用数据类型统一使用equals方法来判断是否相等
这是规矩!
重写equals方法一定要彻底下面插个自己写的例子:
*/
public class Test {
public static void main(String[] args) {
User u1 = new User("zhangsan",new Address("深圳市","龙岗区","90001"));
User u2 = new User("zhangsan",new Address("深圳市","龙岗区","90001"));
User u3 = new User("zhangsan",new Address("深圳市","龙岗区","90002"));
System.out.println(u1.equals(u2));//true
System.out.println(u1.equals(u3));//false
//经过测试没问题,编写的很成功
}
}
class User{
//用户名
String name;
//用户的地址
Address addr;
public User() {
}
public User(String name, Address addr) {
this.name = name;
this.addr = addr;
}
public boolean equals(Object obj){
if(obj == null || !(obj instanceof User))return false;//如果obj是空或者obj不是User的话,直接返回错误
if(obj == this) return true;//如果obj指向的内存地址是this的内存地址的话,那肯定相等,返回正确。
User u =(User) obj;//上面判断过了,所以这里可以直接强转,向下转型。
/*判断name和addr是否相等,注意:此处addr的euqals方法也需要我们重写,因为不写的话addr默认继承那个Object的equals,
那个直接比较的是对象的内存地址,那个不适用,因此需要自己重写。
*/
if(this.name.equals(u.name)&&this.addr.equals(u.addr)) {
return true;
}
return false;
}
}
class Address{
String city;
String street;
String zipcode;
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
public Address() {
}
@Override
public boolean equals(Object obj) {
if(obj == null || !(obj instanceof Address))return false;//传进来的是空或者不是Address对象,直接返回错误,不相等
if(obj == this) return true;//如果传进来的内存地址指向是一样的,那肯定相等
Address a =(Address) obj;//上面判断过,因此直接强转,Object调用不了子类特殊的这些city之类的,因此需要向下转型。
//转型后,判断两者的城市,街道,邮编,是否相等,若相等,那就返回true 不然就是false
if(this.city.equals(a.city)
&&this.street.equals(a.street)
&&this.zipcode.equals(a.zipcode)){
return true;
}
return false;
}
}
运行结果:
经过测试,equals方法重写成功
关于Object类中的finalize()方法 (非重点)
1.在Object类中的源代码 (非重点!!!,不过整的挺好玩)
注意:从jdk9开始已经被禁用
protected void finalize() throws{}
2.finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的。
3.这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法。
4.finalize()方法执行时机;
当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。
5.finalize()方法实际上是sun公司为java程序员准备的一个时机,垃圾销毁的时机,如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法中
6.静态代码块的作用是什么?
static {
…
}
静态代码块在类加载适合执行,并且只执行一次。
这是一个sun准备的类加载时机。
finalize()方法童谣也是sun为程序员准备的一个时机。
这个时机是垃圾回收时机。
GC负责调用这个方法
7.提示:
jva中的垃圾回收器不是轻易启动的,
垃圾太少,或者时间没到,种种条件下
可能启动,也有可能不启动
有一段代码是可以建议垃圾回收器启动的。
System.gc();//建议启动垃圾回收器(只是建议,可能不启动,也可能启动。启动的概率低)
Object中的hashCode()方法:
public native int hashCode();
这个方法不是抽象方法,带有native关键字,底层调用c++
hashCode()方法返回的是哈希码:
实际上就是一个java对象的内存地址,经过哈希算法,得出一个值。
所以hashCode()方法的额执行结果可以等同看作一个java对象的内存地址。
可以了解一下深克隆,浅克隆