💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
[TOC] * 注说明来自 java.lang >[success] # java -- Object 1. **Object** 属于 **java.lang.Object**,是所有Java 语言中类的**根类**,简单的说所有类的最追根溯源其都是继承**java.lang.Object** 2. 默认情况上如果没有指定继承的父类,即没有通过**extends**关键字声明其父类,则其父类为 **java.lang.Object** 类 ~~~ // 默认继承Object public class Circle /* extends Object */ { } ~~~ 3. 因为所有类都继承了**java.lang.Object** 因此他们都具备**java.lang.Object** 的方法可以进行重写 >[info] ## java.lang.Object -- 类方法 | 方法声明 | 功能介绍 | | --- | --- | | Object() | 使用无参方式构造对象 | | boolean equals(Object obj) | 用于判断调用对象是否与参数对象相等。该方法默认比较两个对象的地址是否相等,与 == 运算符的结果一致若希望比较两个对象的内容,则需要重写该方法。若该方法被重写后,则应该重写**hashCode**方法来保证结果的一致性。 | | int hashCode() | 用于获取调用对象的哈希码值(内存地址的编号)。若两个对象调用**equals**方法相等,则各自调用该方法的结果必须相同若两个调用对象equals方法不相等,则各自调用该方法的结果应该不相同。为了使得该方法与equals方法保持一致,需要重写该方法。 | | String toString() | 用于获取调用对象的字符串形式该方法默认返回的字符串为:包名.类名@哈希码值的十六进制为了返回更有意义的数据,需要重写该方法使用print或println打印引用或字符串拼接引用都会自动调用该方法Class<?> getClass() 用于返回调用对象执行时的Class实例,反射机制使用 | | protected Object clone() |创建并返回此对象的副本。 | | void notify()| 唤醒正在此对象监视器上等待的单个线程。 | | void notifyAll()| 唤醒等待此对象监视器的所有线程。 | | void wait() | 导致当前线程等待它被唤醒,通常是 通知或 中断 。 | | void wait​(long timeoutMillis) | 导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。| | void wait​(long timeoutMillis, int nanos) |导致当前线程等待它被唤醒,通常是 通知或 中断 ,或者直到经过一定量的实时。 | >[warning] ### equals 和 hashCode 组合使用 >[danger] ##### equals -- 理解 * 源码方法写法,判读当前this 是否是一个,比较是内存地址指向 ~~~ public boolean equals(Object obj) { return (this == obj); } ~~~ * 下面案例创建的 st1 和 st2 内容虽然相同但**实际地址不同**,因此打印为false ~~~ public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } // 入口 public static void main(String[] args) { Student st1 = new Student(1, "wang"); Student st2 = new Student(1, "wang"); // 使用eq 进行比较 boolean flag = st1.equals(st2); System.out.println(flag); // false } } ~~~ * 重写equals 因为是继承关系所以可以重写,重写后想做到id 相同即认为是同一个人 ~~~ public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } // 重写方法 @Override public boolean equals(Object obj) { // 如果传入是null 防止空指针异常 if (obj == null) return false; // 如果是同一个对象必然相等 if (obj == this) return true; // 先将多态的 obj 向下转型 为当前 Student 类型 // 这样是为了可以调用 Student 类型某些属性和方法 // 传入的obj 必须是当前类创建的实例 if (obj instanceof Student) { Student student = (Student) obj; // 判读如果id 相等 怎认为同一个学生 if (this.id == student.id) return true; } return false; } // 入口 public static void main(String[] args) { Student st1 = new Student(1, "wang"); Student st2 = new Student(1, "wang"); // 使用eq 进行比较 id 相同 boolean flag = st1.equals(st2); // 指向相同 Student st3 = st1; boolean flag1 = st3.equals(st1); // 防止空指针异常 Student st4 = null; boolean flag3 = st1.equals(st4); // 创建对象不同且id 也不同 Student st7 = new Student(2, "wang"); boolean flag4 = st1.equals(st7); System.out.println(flag); // true System.out.println(flag1); // true System.out.println(flag3); // false System.out.println(flag4); // false } } ~~~ >[danger] ##### hashCode 1. 默认来说 **hashCode** 获取调用对象的**哈希码值** 即内存地址的编号 2. java 官方期望如果 实现的**equals** 让两个对象相等,那么两个对象调用**hashCode** 得到值也应该相同 * 重写 hashCode 方法,并且在原来equals 方法判读id 位置替换成判断hashCode ~~~ package javaTest; public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } public int getId() { return id; } // 重写 hascode 方法 // 因为期待是id 相同则默认相等 因此重写hascode 返回为id @Override public int hashCode() { return getId(); } // 重写方法 @Override public boolean equals(Object obj) { // 如果传入是null 防止空指针异常 if (obj == null) return false; // 如果是同一个对象必然相等 if (obj == this) return true; // 先将多态的 obj 向下转型 为当前 Student 类型 // 这样是为了可以调用 Student 类型某些属性和方法 // 传入的obj 必须是当前类创建的实例 if (obj instanceof Student) { Student student = (Student) obj; // 判读如果id 相等 怎认为同一个学生 return this.hashCode() == student.hashCode(); } return false; } // 入口 public static void main(String[] args) { Student st1 = new Student(1, "wang"); Student st2 = new Student(1, "wang"); // 使用eq 进行比较 id 相同 boolean flag = st1.equals(st2); System.out.println(flag); // true } } ~~~ >[danger] ##### 对比 如果是字符串 * 刚才对比是 id 因为刚才Student 的类 id 是数字类型,也满足**hashCode** 返回是数字类型,如果比较是字符写法如下 ~~~ package javaTest; public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } public String getName() { return name; } // 因为getName 是字符串对象,因此它本身也是具有hashCode方法,只需要调用它的hashCode即可 @Override public int hashCode() { return getName().hashCode(); } // 重写方法 @Override public boolean equals(Object obj) { // 如果传入是null 防止空指针异常 if (obj == null) return false; // 如果是同一个对象必然相等 if (obj == this) return true; // 先将多态的 obj 向下转型 为当前 Student 类型 // 这样是为了可以调用 Student 类型某些属性和方法 // 传入的obj 必须是当前类创建的实例 if (obj instanceof Student) { Student student = (Student) obj; // 判读如果name相等 认为同一个学生 // return this.hashCode() == student.hashCode(); // getName 是 String 类型 双等比较是 内存地址,如果想比较内容使用equals return getName().equals(student.getName()); } return false; } // 入口 public static void main(String[] args) { Student st1 = new Student(1, "wang1"); Student st2 = new Student(1, "wang"); // 使用eq 进行比较 name 相同 boolean flag = st1.equals(st2); System.out.println(flag); // false } } ~~~ * 编译器自动生成重写 判断name 和 age 都要相同 ~~~ package javaTest; public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } @Override 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 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (id != other.id) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } public static void main(String[] args) { Student st1 = new Student(1, "wang1"); Student st2 = new Student(1, "wang"); // 使用eq 进行比较 name 相同 boolean flag = st1.equals(st2); System.out.println(flag); // false } } ~~~ >[warning] ### toString * 用print或println打印引用或字符串拼接引用都会自动调用该方法 ~~~ package javaTest; public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + "]"; } } ~~~ > [warning] ### * 用于返回调用对象执行时的Class实例,反射机制使用 ~~~ package javaTest; public class Student { int id = 0; String name = ""; Student(int id, String name) { this.id = id; this.name = name; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + id; return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; // 判读是否是同一个类 if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (id != other.id) return false; return true; } } ~~~