object类是所有类的顶层父类,所有的类都直接或间接的继承自他。
object类位于Java.lang包中,Java.lang 中包括着Java最基础的核心类在编译时会自动导入。
object类中包含的常用的方法如下所示:
1. public final Class getClass() //a:返回此 Object 的运行时类。
2. public int hashCode() //a:返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。
3. public boolean equals(Object obj) //判断其他对象与此对象是否“相等”
4. protected native Object clone() throws CloneNotSupportedException //创建并返回此对象的一个副本
5. public String toString() //返回对象的字符串表示
6. public final native void notify() //唤醒在此对象监视器上等待的单个线程
7. public final native void notifyAll() //唤醒在此对象监视器上等待的所有线程
8. public final native void wait(long timeout) throws InterruptedException //使当前对象的线程等待 timeout 时长
9. public final void wait(long timeout, int nanos) throws InterruptedException //使当前对象的线程等待 timeout 时长,或其他线程中断当前线程
10. public final void wait() throws InterruptedException //使当前对象的线程等待
11. protected void finalize() throws Throwable {} //垃圾回收时调用该方法
涉及多线程的方法以后在更新,目前还没有学习。
get Class()
- 返回此object的运行时类。
- 可以通过Class类中的一个人方法获取对象的真实类的全名称
public String getName()
{
//Class<?> getClass ()
//返回此 Object 的运行时类。
//Object.class------->当这个字节码文件加载进内存后,然后JVM会为字节码文件创建一个对象---->我可以通过getClass()方法获取这个字节码文件对象
Object obj = new Object();
Class aClass = obj.getClass(); //Class 表示字节码文件类
Object obj2 = new Object();
Class aClass1 = obj2.getClass();
System.out.println(obj == obj2); //false
// Object.class--->字节码文件的对象
System.out.println(aClass == aClass1);//true
//反射机制---->需要用到字节码文件对象
}
equals
a:指示其他某个对象是否与此对象“相等”。
源代码:
public boolean equals(Object obj) {
return (this == obj);
}
b
默认情况下比较的是对象的引用是否相同。
c:由于比较对象的引用没有意义,一般建议重写该方法。一般用于比较成员变量的值是否相等。
==和equals()的区别
- 对于基本类型,==判断的时两个值是否相等,基本类型没有equals()方法。
-
- 对于引用类型,==判断连个变量是否引用同一个对象,而equals()判断引用的对象是否等价。
Integer x = new Integer(1);
Integer y = new Integer(1);
System.out.println(x.equals(y)); // true
System.out.println(x == y); // false
实现
Object的equals方法对于任何非空引用值 x,y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true,因此通常需要在自定义的类中重写 equals 方法,让它比较两个对象的成员变量值是否相等,一样就返回true。
Student s1 = new Student("张三", 23);
Student s2 = new Student("张三", 23);
// Teacher teacher = new Teacher();
System.out.println(s1==s2);//false
System.out.println(s1.equals(s2)); //true
class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//@Override
//public String toString() {
// return "姓名"+this.name+"=== 年龄"+this.age;
//}
//软件可以帮我们自动重写toString方法,去打印成员变量的值
@Override
public String toString() {
return "Student{" +
"name 姓名='" + name + '\'' +
", age 年龄=" + age +
'}';
}
@Override//对equals方法进行重写
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Student student = (Student) o;
return age == student.age &&
Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
注意
当重写equals方法时,需要重写 hashCode 方法,以维护 hashCode 方法的规定,即等价对象具有相等的哈希码。
hashCode()
hasCode() 返回散列值,而 equals() 是用来判断两个对象是否等价。等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价。
在覆盖 equals() 方法时应当总是覆盖 hashCode() 方法,保证等价的两个对象散列值也相等。
toString
默认返回对象的16进制地址值,一般情况下我们认为打印地址值是意义不大的,一般情况下我们希望打印变量的值,这个时候我们就需要对object的tostring方法进行重写。
public class MyTest {
public static void main(String[] args) {
Student student = new Student();
System.out.println(student.toString());
System.out.println("---------------------------------------");
Student student1 = new Student("zhangsan", 13);
System.out.println(student1.toString());
//父类这个toString方法的默认实现,老是打印对象的地址值,我觉得老打印这个对象的地址值,对我来说意义不大,
//我想打印一些,我认为有意义的数据
//请问怎么办?子类对父类方法实现不满意。这个时候我们可以重写父类toString()方法,看一些我想要看的数据
//比如,我让toString()方法,答应成员变量的值,我觉得还有用一些
}
}
class Student{
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//@Override
//public String toString() {
// return "姓名"+this.name+"=== 年龄"+this.age;
//}
//软件可以帮我们自动重写toString方法,去打印成员变量的值
@Override
public String toString() {
return "Student{" +
"name 姓名='" + name + '\'' +
", age 年龄=" + age +
'}';
}
}
clone()
- 你想要克隆这个类的对象,需要让这个类实现一个 Cloneable 接口
- Cloneable 这个接口里面没有任何抽象方法,他就是一个标记接口
- clone() 是 Object 的 protected 方法,它不是 public,一个类不重写,其它类就不能直接去调用该类实例的 clone() 方法。
不实现Cloneable
public class CloneExample {
privateint a;
private int b;}
CloneExample e1 = newCloneExample();
CloneExample e2 = e1.clone();
// 'clone()' has protected access in 'java.lang.Object'
实现Cloneable,并且重写clone方法
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
//protected Object clone ()
//创建并返回此对象的一个副本。
Dog dog = new Dog("小白",3);
System.out.println(dog.name);
System.out.println(dog.age);
//克隆对象
Dog dog2 = (Dog) dog.clone();
dog2.name="旺财";
System.out.println(dog2.name);
System.out.println(dog2.age);
}
}
//Cloneable 你想要克隆这个类的对象,需要让这个类实现一个 Cloneable 接口
//Cloneable 这个接口里面没有任何抽象方法,他就是一个标记接口
class Dog extends Object implements Cloneable{
public String name;
public int age;
public Dog(String name, int age) {
this.name = name;
this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
//还是去调用父类的克隆逻辑
return super.clone();
}
}
克隆有深克隆和浅克隆之分
- 浅克隆:拷贝对象和原始对象的引用类型引用同一个对象;你克隆过来的对象中,只是克隆了另外一个对象的地址值
- 深克隆:拷贝对象和原始对象的引用类型引用不同对象。