Object类中hashCode()方法、equals()方法、getClass()方法、toString()方法和clone()方法总结

hashCode()方法

在弄清楚hashCode之前我们需要先了解一下Object类

//Object 是我们所有类的顶层父类,所有类都是直接或间接继承自他
//创建Object类的对象 :Object obj = new Object();

Object 类和我们学过的所有类具有相同的性质,只不过它是所有类的顶层父类。

下面是hashCode()介绍

//hashCode() 返回一个对象的哈希码值
//不同对象的哈希码值不一样
public class MyTest {
    public static void main(String[] args) {
        //Object 是我们所有类的顶层父类,所有类都是直接或间接继承自他
        Object obj = new Object();  //创建Object类的对象
        //object中常用的方法
        //hashCode() 返回一个对象的哈希码值
        int i = obj.hashCode();
        System.out.println(i);
        Object o = new Object();
        int i1 = o.hashCode();
        System.out.println(i1);
        //不同对象的哈希码值不一样
    }
}

equals()方法

equals()是用来比较两个对象的地址值是否相等,调用方法为:

//  boolean equals (Object obj)  返回的是真/假值(true or false)
//   boolean X = a.equals(b)    比较a与b的地址值,并返回给X

equals()方法重写

因为有些时候我们并不是想去比较两个对象的地址值是否相等,而是想要比较两个对象中的成员变量是否相等,因此我们会对equals()方法进行重写。

public class Student {
    String name;
    int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
      @Override
    public boolean equals(Object obj) {
        //instanceof可以判断一个引用或者对象,是不是该类型的一个引用
        //我认为两个对象的成员变量一模一样,我就认为两个对象一样
        //向下转型
        //优化比较效率
       if(this==obj)
            return true;
        if(!(obj instanceof Student))
        {
            return false;
        }
       Student stu = (Student) obj;
//“张三”==“张三”有可能是false,string类认为父类object中的equals默认比较方式意义不大
//string类重写了equals方法,取比较两个字符串的字面内容是否相同。
        return this.name.equals(stu.name)&&this.age==stu.age;
    }
}

上面从@Override开始就是对equals方法的重写,不仅考虑了两个对象的成员一致问题,还考虑到了不同类之间肯定不相等的问题(这里用到了instanceof这个比较运算符)以及同一个对象必然相等的问题,这就优化了equals()方法,提高了运行效率。
当然,我们可以用快捷方式实现上述重写部分的代码(狗头狗头狗头),按住Ctrl+O选择重写equals(obj:Object):boolean,即可生成重写部分的代码,如下:

    @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);
    }
    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
public class MyTest2 {
    public static void main(String[] args) {
        //  boolean equals (Object obj)  比较两个对象的地址值是否相等
        Object obj1 = new Object();
        Object obj2 = new Object();
        boolean equals = obj1.equals(obj2);
        System.out.println(equals);
        Object stu1 = new Student("张三", 24);
        Object stu2 = new Student("李四", 23);
        Object stu3 = new Student("张三", 24);
        Object dog = new Dog("旺财", 2);
        System.out.println(stu1.equals(dog));
        System.out.println(stu1.equals(stu1));
        System.out.println(stu1.equals(stu2));
        System.out.println(stu1.equals(stu3));
    }
}
class Dog{
    String name ;
    int age;
    public Dog() {}
  
    public Dog(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

getClass()方法

在java中,万物皆是对象,因此 .class 文件也是一个对象(例:Student.class 加载进内存之后,JVM就会为Student.class创建一个对象),可以通过getClass()这个方法将 .class 文件获取出来。需要注意的是同一个类只有一个字节码文件,通过equals()方法来说明一下 。

public class MyTestgetClass {
    public static void main(String[] args) {
        //Class<?>getClass()按Java万物皆对象的思想,那么他会把.class文件看做一个对象
        //Student.class 加载进内存后,JVM就会为Student.class创建一个对象
        //我们可以把这个对象获取出来用,怎么获取?用getClass()这个方法来获取
        Student student1 = new Student();
        Student student2 = new Student();
        Class aClass1 = student1.getClass();
        Class aClass2 = student2.getClass();
        System.out.println(student1.equals(student2));
        System.out.println(aClass1.equals(aClass2));
    }
}
class Student{
}

toString()方法

toString()方法的主要作用是返回对象的字符串形式,这一般不是我们想要的结果,因此,我们会对该方法进行重写。判断是否重写,只需调用该方法看返回值是否为字符串,若不是,则重写了该方法。
public String toString()
a:返回该对象的字符串表示。
源代码:
public String toString() {
return getClass().getName() + “@” + Integer.toHexString(hashCode());
}
b:它的值等于:
getClass().getName() + ‘@’ + Integer.toHexString(hashCode())
c:由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。
怎么重写, 一般是将该类的所有的成员变量组成返回即可

public class MyTesttoString {
    public static void main(String[] args) {
        Student student = new Student("张三",20);
        System.out.println(student.toString());
//        public String toString() {
//            return getClass().getName() + "@" +           Integer.toHexString(hashCode());
//        }
    }
}
class Student{
    String name;
    int age;

    public Student() {
    }

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

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

clone()方法(这里只对浅克隆做介绍)

  1. 克隆的创建:

     // protect Object clone() 创建并返回此对象一个副本
    
public class MyTestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        //protect Object clone() 创建并返回此对象一个副本
        Dog dog = new Dog();
        Object clone = dog.clone();//克隆对象不会执行构造方法
    }
}
//Cloneable 里面没有任何抽象方法,这种接口,我们称之为标记即可,作用就是让JVM知道,我要克隆
class Dog implements Cloneable{
 }

clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把该方法的权限修饰符改为public, 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。Cloneable接口只不过是一个标识接口而已,没有任何方法。并且在main方法中“扔掉”了一个克隆会引起的“bug”, throws CloneNotSupportedException,这样就可以成功调用 clone()方法。

  1. 还要强调的是克隆对象不会调用构造方法
public class MyTestClone {
    public static void main(String[] args) throws CloneNotSupportedException {
        Dog dog = new Dog();
        Object clone = dog.clone();
        Dog dog1= (Dog) clone;//克隆对象不会执行构造方法
    }
}
class Dog implements Cloneable{
    public Dog() {
        System.out.println("构造方法执行了");
    }
}
  1. 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。就是说地址给了克隆对象一份,这样的话,克隆的对象也会更改地址所指向的值,使得被克隆的对象内容被改变
public class MyTestDeepClone {
    //浅克隆
    public static void main(String[] args) throws CloneNotSupportedException {
        DogFood dogFood = new DogFood("王中王");
        Dog dog1 = new Dog("旺财", 2, dogFood);
        dog1.food.name = "双汇";
        Dog dog2 = (Dog) dog1.clone();
        dog2.name="来福";
        dog2.age=2;
        dog2.food.name="金锣";
        System.out.println(dog1.name+"=="+dog1.age+"=="+dog1.food.name);
        System.out.println(dog2.name+"=="+dog2.age+"=="+dog2.food.name);

    }
}

class Dog implements Cloneable {
    String name;
    int age;
    DogFood food;

    public Dog() {
    }

    public Dog(String name, int age, DogFood food) {
        this.name = name;
        this.age = age;
        this.food = food;
    }

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

class DogFood {
    String name;

    public DogFood() {
    }

    public DogFood(String name) {
        this.name = name;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值