Object类
前言,观察代码:
1.定义一个User类
public class User { private int id; private String name; // 1.无参 和 有参 构造 public User() { super(); } public User(int id, String name) { super(); setId(id); setName(name); } public User( String name) { super(); setName(name); } // 2.get、set public int getId() { return id; } public void setId(int id) { if(id>0) this.id=id; else System.out.println("id值不能小于0,请重新输入......."); } public String getName() { return name; } public void setName(String name) { this.name=name; } @Override // 重写了equals()方法 //Object obj = u2; 父类引用指向子类的对象,形成了多态 public boolean equals(Object obj){ //1.当两个引用指向的内存地址相同时,则两个对象的内容一定相同 if(this == obj) return true; //2.当调用对象不为空,参数对象为空时,则两个对象的内容一定不相同 else if(obj == null) return false; //3.当两个引用都不为空时,则比较里面的内容,也就是比较编号 // 调用对象一定是User类型,但是参数对象属于 Object类型,obj里面没有id属性 else if(obj instanceof User){ User tu = (User)obj; return getId() == tu.getId(); // getId() == tu.getId();结果是boolean类型,要么是ture要么是false } //4.当两个引用都不为空时,并且参数对象也不是User类型的,则返回不相同 return false; } // @Override // 马如忠版本 // public int hashCode(){ // int type = 12; // return 31*type + getId(); // } @Override // 重写了hashc()方法 public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override // 重写了toString()方法 public String toString() { return "User [id=" + id + ", name=" + name + "]"; } }
2.测试类
package com.monkey1032; public class UserTest { public static void main(String[] args) { User u1 = new User(23,"James"); // 创建了一个u1对象 User u2 = new User(23,"James"); // 创建了一个u2对象 System.out.println("-----------------------------------------------------------------"); System.out.println("当 == 用于比较引用类型的对象时,比较的是两对象的地址是否相同"); System.out.println(); System.out.println((u1==u2)+"---u1和u2的地址不同"); System.out.println("-----------------------------------------------------------------"); System.out.println("对equals()方法进行了重写:比较两个对象的内容是否相等"); System.out.println(); System.out.println(u1.equals(u2)+"-----u1和u2的内容相同"); System.out.println("-----------------------------------------------------------------"); System.out.println("对hashCode()方法进行了重写:若两个对象的内容一致,则它们的哈希码相等"); System.out.println(); System.out.println("u1的哈希码值:"+u1.hashCode()); System.out.println(); System.out.println("u2的哈希码值:"+u2.hashCode()); System.out.println("-----------------------------------------------------------------"); System.out.println("对toString()方法进行了重写:则打印对象的对应属性值"); System.out.println(); System.out.println("u1对象----"+u1); System.out.println(); System.out.println("u2对象----"+u2); } }
打印结果:
----------------------------------------------------------------- 当 == 用于比较引用类型的对象时,比较的是两对象的地址是否相同 false---u1和u2的地址不同 ----------------------------------------------------------------- 对equals()方法进行了重写:比较两个对象的内容是否相等 true-----u1和u2的内容相同 ----------------------------------------------------------------- 对hashCode()方法进行了重写:若两个对象的内容一致,则它们的哈希码相等 u1的哈希码值:71339950 u2的哈希码值:71339950 -----------------------------------------------------------------
对toString()方法进行了重写:则打印对象的对应属性值
u1对象----User [id=23, name=James]
u2对象----User [id=23, name=James]
以上代码中,是将继承自Object类中的equals()、hashCode()、toString()方法都进行了对应内容的重写
现在若将User类中的 equals()、hashCode()、toString()方法都 注释掉,则默认调用的是超类Object类中的这些方法
看看打印结果如何?
public class UserTest { public static void main(String[] args) { User u1 = new User(23,"James"); // 创建了一个u1对象 User u2 = new User(23,"James"); // 创建了一个u2对象 System.out.println("-----------------------------------------------------------------"); System.out.println("当 == 用于比较引用类型的对象时,比较的是两对象的地址是否相同"); System.out.println(); System.out.println((u1==u2)+"---u1和u2的地址不同"); System.out.println("-----------------------------------------------------------------"); System.out.println("Obeject类中的equals():默认比较的是两对象的地址是否相同"); System.out.println(); System.out.println(u1.equals(u2)+"-----u1和u2的地址不同"); System.out.println("-----------------------------------------------------------------"); System.out.println("Obeject类中的hashCode():返回该对象的哈希码值。"); System.out.println(); System.out.println("u1的哈希码值:"+u1.hashCode()); System.out.println(); System.out.println("u2的哈希码值:"+u2.hashCode()); System.out.println("-----------------------------------------------------------------"); System.out.println("Obeject类中的toString(),打印出对象的为: 包名.类名@哈希码的无符号十六进制形式"); System.out.println(); System.out.println("u1对象----"+u1); System.out.println(); System.out.println("u2对象----"+u2); } }
结果:
----------------------------------------------------------------- 当 == 用于比较引用类型的对象时,比较的是两对象的地址是否相同 false---u1和u2的地址不同 ----------------------------------------------------------------- Obeject类中的equals():默认比较的是两对象的地址是否相同 false-----u1和u2的地址不同 ----------------------------------------------------------------- Obeject类中的hashCode():返回该对象的哈希码值。 u1的哈希码值:2018699554 u2的哈希码值:1311053135 ----------------------------------------------------------------- Obeject类中的toString(),打印出对象的为: 包名.类名@哈希码的无符号十六进制形式 u1对象----com.monkey1033.User@7852e922 u2对象----com.monkey1033.User@4e25154f
总结:
java.lang.Object类是Java类层次结构中的根类,是所有java类的超类。因此所有的类都能够调用Object类拥有的方法。
boolean equals(Object obj)
---- 默认比较的是 两个对象的地址是否相等,效果等同于 ==
---- 形参是Object类型的引用,因此实参可以传递本类对象,也可以传递子类对象(形成多态)
---- 具有 自反性、对称性、传递性、一致性、非空性
--- 若希望该方法比较两个对象中的内容,则需要子类对该方法进行重写。
--- 编程建议:子类只要重写了该方法,记得同时重写hashCode()方法。
int hashCode()
--- 用于返回调用对象的哈希码值 (理解成内存地址的编号)
--- 只要equals()方法的比较信息没有改变,则调用该方法的都应该返回相同的整数。
--- 编程经验:
--- equals()比较两个对象的结果 相等,则两个对象调用该方法返回的整数相同。
--- equals()比较两个对象的结果 不相等,则对象调用该方法返回的整数可以相同,但最好不相同。
String toString()
--- 用于返回调用对象的字符串形式,格式为: 包名.类名@哈希码的无符号十六进制形式
--- 若希望打印其他内容时,则需要对该方法进行重写。
---- print() / println() 方法打印引用时,会自动调用 toString()方法。
---- 若使用 + 加号 进行字符串连接时,也会自动调用toString()方法。
子类若不自行对超类Object类的方法进行重写,则调用父类的方法。若对继承自Object中的方法进行了重写,则调用子类重写的方法。
一、Object类概述
二、Object类中3个使用频率最高的方法:
三、 equals()方法
四、hashCode()方法
五、为何重写了equals()方法,则也要重写hashCode()方法?
六、关于 == 和 equals()的区别和联系
补充方法:
void wait( ) -用于让当前线程进入阻塞状态,直到其他线程调用notify()等方法。否则一直保持阻塞状态。
void wait(long timeout) -用于让当前线程进入阻塞状态,直到其他线程调用notify()等方法 或者指定的时间到了,
否 则一直保持阻塞。
void notify( ) -用于消除当前对象锁上的单个线程的阻塞状态。(随机,指定不了)
void notifyAll( ) -用于唤醒所有阻塞状态的线程。