Bootstrap

Java万物之父Object

目录

为什么引入Object类

包装类

Object的toString方法

Object的equlas方法 

Object的hashCode 


 


简介

Object是Java的万物之母,全名称java.lang.Object(包名.类名),它是所有类的默认父类,无需使用extends来定义,只要是class声明的类都是Object的子类

为什么引入Object类

因为它是所有的类的父类,所以可以使用Object引用来接收所有的类的对象,能实现参数的最高统一化

  

Object子类的扩展

JDK对Object进行了扩展,Object类可以接收所有的引用数据类型(类,接口,数组)

包装类

  • 因为Object接收不了八大基本数据类型,所以包装类应运而生,为了让Object能够接收
  • 基本数据类型的默认值在很多场景下会产生误导,但引用类型的默认值是null就不会,比如费率使用double类型,默认值是0.0,有可能我们的费率就是0.0,那这个0.0到底是默认值还是本来就是0.0就无法区分

包装类的使用

 自动拆装箱

 

 自动拆箱发生在进行数学运算的时候

包装类的比较

包装类也是类,所以值的比较也是需要用equals

包装类的常量池 

 当使用整型包装类的自动拆装箱时,JVM会缓存相应的数值,Integer常量池会默认在-128到127之间取值,都会缓存到常量池中

阿里编码规范: 所有POJO(普通)类的成员变量一律使用包装类来代替基本类型

Object的toString方法

在Object类中定义了toString方法,所以所有类都会继承这个方法,所以System.out.println(任意引用类型)——>如果没有就会去调用Object类的toString方法(会一直往父类找,找到第一个toString方法)

package Object_Test;
class Person1{
    @Override
    public String toString(){
        return "这是Person1的toString方法";
    }
}
class Student1 extends Person1{

}
class Dog1{

}
public class Test {
    public static void main(String[] args) {
        Student1 student=new Student1();
        Dog1 dog=new Dog1();
        System.out.println(student);
        System.out.println(dog);

    }
}

Object的equlas方法 

Java中的引用数据类型直接比较不能用==,因为==比较的是地址,如果想比较其属性值应该用equlas方法

 覆写equals方法

package Object_Test;

import java.util.Objects;

class Student2{
    String name;

    public Student2(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "Student1{" +
                "name='" + name + '\'' +
                '}';
    }

    @Override
    public boolean equals(Object o) {
      if (this==o){
          return true;
          //1表示比较的是同一个对象
      }
      if (o instanceof Student2){
          //2当前两个对象确实不是指向一个对象,但是两个对象
          //的类型是相同的,这样才有是属性相同的可能
          Student2 stu=(Student2) o;
          return this.name.equals(stu.name);//因为String类型也是引用类型
          //所以比较也需要equals方法,String类已经覆写过这个方法
      }
      return false;//3当前比较的对象不是一个类型
    }

}
public class equals_test {
    public static void main(String[] args) {
        Student2 lsc=new Student2("刘颂成");
        Student2 wwd=new Student2("汪汪队");
        Student2 lsc1=new Student2("刘颂成");
        System.out.println(lsc==lsc1);//false
        System.out.println(lsc.equals(lsc1));//true
    }
}

Object的hashCode 

源码

  •  使用C++的基础上的哈希函数
  • Object提供的hashCode可以将任意的对象转换为int,不同的对象(地址不同,这个是取决于Object提供的equals方法)会转换为不同的int
  • 原则上自定义的类若需要保存到HashMap哈希表中,不能直接使用Object提供的hashCode,需要覆写这个方法

不同对象对应不同的哈希值

  • Person1和Person3是同一个对象
  • Person1和Person2是不同的对象 

如何覆写该方法

两个原则

  • equals相同的两个对象,hashcode必须相同
  • hashCode相同的两个对象,equals不一定相同

equals相同的两个对象,在Map中就被认为是同一个对象。这样的对象在哈希表中只能存在一个,在哈希表中只有equals和哈希值都相同的对象是唯一对象,在Object中equals中默认是比较地址值的,所以不同的对象拥有不同的hashCode值

package Object_Test;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

class newPerson{
    private String name;
    private int age;

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

    @Override
    public boolean equals(Object o) {
        if(this==o){
            return true;
        }
        if (o instanceof newPerson){
            //如果是同一个类型
            return this.age==((newPerson) o).age&&this.name.equals(((newPerson) o).name);
        }
        return false;
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
        //Objects是工具类,此时HashMap就会按照名字和年龄相同的当作一个对象
    }

    @Override
    public String toString() {
        return "newPerson{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class Object_hashCode {
    public static void main(String[] args) {
        newPerson Person1=new newPerson("lsc",18);
        newPerson Person2=new newPerson("zzz",33);
        newPerson Person3=new newPerson("lsc",18);
        Map<newPerson,String> map=new HashMap<>();
        map.put(Person1,"111");
        map.put(Person2,"222");
        map.put(Person3,"333");
        System.out.println(map);
    }
}

  • Person3和Person1本质上不是一个对象,因为其地址值不同,但是我们覆写了HashCode和equals,按照我们覆写的原则来说,在哈希表中 name和age相同的newPerson对象被认为是同一个对象
  • 所以想按照我们自己写HashCode进行计算哈希值,那么我们必须要覆写equals
;