目录
简介
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