Java中的Object类

在学习继承的时候,提到过,所有的类都是直接或者间接地继承Object类。由此可见,Object类是很重要的一个类。今天就来谈谈Object类。

类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
下面来谈谈Object类中的方法。

构造方法

在这里插入图片描述
构造方法是公共的。可以创建对象。

getClass()方法

在这里插入图片描述
该方法是一个公共的final的方法。

  • 方法 返回此 Object 的运行时类。返回的 Class 对象是由所表示类的 static synchronized 方法锁定的对象。
  • 可以通过Class类中的一个方法,获取对象的真实类的全名称。
    public String getName();

举例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.getClass());
    }
}

结果:

class java.lang.Object

hashCode()方法

在这里插入图片描述
方法是公共的方法,返回值类型为int类型。

  • 方法返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
  • 不同对象的,hashCode()一般来说不会相同。但是,同一个对象的hashCode()值肯定相同。
  • 不是对象的实际地址值,可以理解为逻辑地址值。

举例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o.hashCode());
    }
}

结果:

460141958

toString()方法

在这里插入图片描述
方法为公共的方法,返回值类型为String。

  • 返回该对象的字符串表示。
    源代码:
    public String toString() {
    return getClass().getName() + “@” + Integer.toHexString(hashCode());
    }
  • 它的值等于:
    getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
  • 由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。(怎么重写, 一般是将该类的所有的成员变量组成返回即可)
  • 在代码里,直接输出对应的名称,就是调用对象的toString()方法。

举例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(o);
    }
}

结果:

java.lang.Object@1b6d3586

重写toString()方法:

public class Demo {
    public static void main(String[] args) {
        Object o = new Student();
        System.out.println(o);
    }
}

class Student{
    String name;
    int age;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

重写后的结果为:

Student{name='null', age=0}

equals()方法

在这里插入图片描述
方法为公共的方法,返回值类型为boolean类型。

  • 指示其他某个对象是否与此对象“相等”。
    源代码:
    public boolean equals(Object obj) {
    return (this == obj);
    }
  • 默认情况下比较的是对象的引用是否相同。
  • 由于比较对象的引用没有意义,一般建议重写该方法。一般用于比较成员变量的值是否相等。

==和equals()的区别

  • ==:是一个关系运算符,用于比较运算符的两端是否相等。若为比较运算符的两端为基本数据类型,则比较的是值是否相等;若为对象,则比较的是对象的地址值是否相等。
  • equals():是一个方法,默认比较的是两个对象的地址值是否相等。

举例:

public class Demo {
    public static void main(String[] args) {
        Object o = new Object();
        Object o1 = new Object();
        System.out.println(o.equals(o1));
    }
}

结果:

false

重写后的equals()方法:

public class Demo {
    public static void main(String[] args) {
        Student s1 = new Student("小明",20);
        Student s2 = new Student("小明",20);
        System.out.println(s1.equals(s2));
    }
}

class Student {
    String name;
    int age;

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    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);
    }
}

结果为:

true

clone()方法

在这里插入图片描述
方法是受保护的,只能在本类、同一包下(子类和无关类)、不同包下(子类)三种情况下调用clone()方法。

  • 由于clone()的权限修饰符是受保护的,在用的时候,需要让该类重写该方法,并把该方法的权限修饰符改为public。
  • 使用clone()方法采用的是浅克隆的方式。

在这里插入图片描述

对象浅克隆要注意的细节

  • 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。
  • Cloneable接口只不过是一个标识接口而已,没有任何方法。
  • 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
  • 对象的浅克隆也不会调用到构造方法的。
    举例:
public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Teacher teacher = new Teacher("张老师",35);
        Teacher teacher1 = (Teacher) teacher.clone();

    }
}

class Teacher extends Object implements Cloneable{
    
    String name;
    int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public void show() {
        System.out.println(name);
        System.out.println(age);
    }
}

teacher和teacher1指向的是一模一样的内存空间,但两个内存空间的地址值是不一样的,即改变一个内存空间的变量值不会影响另一个空间的变量的值。
举例:

public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException{
        Teacher teacher = new Teacher("张老师",35);
        teacher.show();
        Teacher teacher1 = (Teacher) teacher.clone();
        teacher1.name="刘老师";
        teacher1.age=30;
        teacher1.show();

    }
}

class Teacher extends Object implements Cloneable{

    String name;
    int age;

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public void show() {
        System.out.println(name);
        System.out.println(age);
    }
}

结果:

张老师
35
刘老师
30

在这里插入图片描述

针对 “对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。” 这种情况进行分析:
举例说明:

public class Demo2 {
    public static void main(String[] args) throws CloneNotSupportedException {
        Teacher teacher = new Teacher("张老师", 35);
        teacher.play.name = "打篮球";
        teacher.show();
        Teacher teacher1 = (Teacher) teacher.clone();
        teacher1.name = "刘老师";
        teacher1.age = 30;
        teacher1.play.name = "踢足球";
        teacher1.show();
        teacher.show();


    }
}

class Play {
    String name;

    public Play() {
    }

}

class Teacher extends Object implements Cloneable {

    String name;
    int age;
    Play play = new Play();

    public Teacher(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    public void show() {
        System.out.println(name + play.name);
    }
}

结果:

张老师打篮球
刘老师踢足球
张老师踢足球

分析:
在这里插入图片描述
对象的深克隆:采用IO流来实现。使用 ObjectOutputStream 将对象写入文件中,然后再用ObjectInputStream读取回来。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章