Object类详解
免责声明:java基础资料均来自于韩顺平老师的《循序渐进学Java零基础》教案,具体视频内容可以去B站观看,这些资料仅用于学习交流,不得转载用于商业活动
1.1 equals方法
1.1.1 ==和equals的对比
- ==是一个比较运算符
- ==:既可以判断基本类型,又可以判断引用类型
- ==:如果判断基本类型,判断的是值是否相等
- ==:如果判断引用类型,判断的是地址是否相等,即判定是不是同一个对象
- equals:是Object类中的方法,只能判断引用类型
- 默认判断的是地址是否相等,子类中往往重写该方法,用于判断内容是否相等
1.1.2 Object的equals方法
//Object的equals方法默认就是比较对象地址是否相同 //也就是判断两个对象是不是同一个对象 public boolean equals(Object Obj){ return (this == Obj); }
1.1.3 String类重写equals方法
1 //String类的equals把Object的equals方法重写了,变成了比较两个字符串值是否相同 2 @Override 3 public boolean equals(Object anObject){ 4 if(this == anObject) {//如果是同一个对象 5 return true;//true 6 } 7 if(anObject instanceof String){//判断类型 8 String anotherString=(String) anObject;//向下转型 9 int n=value.length; 10 if(n == anotherString.value.length){//如果长度相同 11 char v1[] = value; 12 char v2[] = anObject.value; 13 int i = 0; 14 while(n-- != 0){//然后一个一个的比较字符 15 if(v1[i] != v2[i]) 16 return false; 17 i++; 18 } 19 return true;//如果两个字符串的所有字符都相等,则返回true 20 } 21 } 22 return false;//如果比较的不是字符串,则返回false 23 }
1.1.4 Integer类重写equals方法
//Integer也重写了Object的equals方法, //变成了判断两个值是否相同 public boolean equals(Object obj){ if(obj instanceof Integer){ return value == ((Integer)obj).intValue(); } return false; }
Equals01.java
1 public class Equals01 { 2 public static void main(String[] args){ 3 A a = new A(); 4 A b = a; 5 A c = b; 6 System.out.println(a == c);//true 7 System.out.println(b == c); //true 8 B bObj = a; 9 System.out.println(bObj == c);//true 10 int num1 = 10; 11 double num2 = 10.0; 12 System.out.println(num1 == num2); //基本数据类型,判断值是否相等 13 14 Integer integer1 = new Integer(1000); 15 Integer integer2 = new Integer(1000); 16 System.out.println(integer1 == integer2); //false 17 System.out.println(integer1.equals(integer2));//true 18 19 String str1 = new String("hello"); 20 String str2 = new String("hello"); 21 System.out.println(str1 == str2); //false 22 System.out.println(str1.equals(str2)); //true 23 } 24 25 } 26 27 class B{} 28 class A extends B{}
1.1.5 如何重写equals方法
例如:判断两个Person对象的内容是否相等,如果两个Person对象的各个属性值都一样则返回true,否则返回false
1 public class Equals02 { 2 public static void main(String[] args){ 3 Person person1 = new Person("jack",10,'男'); 4 Person person2 = new Person("jack",20,'男'); 5 System.out.println(person1.equals(person2));//false 6 7 //当使用 == 来判断两个变量是否相等时,如果两个变量是基本类型变量, 8 // 且都是数值类型(不一定要求数据类型严格相同),则只要两个变量的值相等,就返回true。 9 int i = 65; 10 float f = 65.0f; 11 System.out.println("65和65.0f是否相等?"+(i == f));//true 12 } 13 } 14 15 //判断两个Person对象的内容是否相等 16 //如果两个Person对象的各个属性值都一样,则返回true,否则返回false 17 class Person{//extends Object 18 private String name; 19 private int age; 20 private char gender; 21 22 public Person(String name,int age,char gender){ 23 this.name = name; 24 this.age = age; 25 this.gender = gender; 26 } 27 28 public String getName(){ 29 return name; 30 } 31 32 public void setName(String name){ 33 this.name = name; 34 } 35 36 public int getAge(){ 37 return age; 38 } 39 40 public void setAge(int age){ 41 this.age = age; 42 } 43 44 public char getGender(){ 45 return gender; 46 } 47 48 public void setGender(char gender){ 49 this.gender = gender; 50 } 51 52 //重写Object的equals方法 53 public boolean equals(Object obj){ 54 //判断如果比较的两个对象是同一个对象,则返回true 55 if(this == obj){ 56 return true; 57 } 58 59 //类型判断 60 if(obj instanceof Person){//是Person,我们才比较 61 //进行向下转型,因为我们需要得到obj的各个属性 62 Person p = (Person) obj; 63 return this.name.equals(p.name) 64 && this.age == p.age 65 && this.gender == p.gender; 66 } 67 //如果不是Person,则直接返回false 68 return false; 69 } 70 }
1.2 hashCode方法
小结:
- 提高具有哈希结构的容器的效率
- 两个引用,如果指向的是同一个对象,则哈希值肯定是一样的
- 两个引用,如果指向的是不同对象,则哈希值是不一样的
- 哈希值主要根据地址号来的,不能完全将哈希值等价于地址
public class HashCode_ { public static void main(String[] args){ AA aa = new AA(); AA aa2 = new AA(); AA aa3 = aa; System.out.println("aa.hashCode=" + aa.hashCode());//aa.hashCode=1627674070 System.out.println("aa2.hashCode=" + aa2.hashCode());//aa2.hashCode=1360875712 System.out.println("aa3.hashCode=" + aa3.hashCode());//aa3.hashCode=1627674070 } } class AA{}
1.3 toString方法
1)基本介绍
默认返回:全类名+@+哈希值的十六进制
子类往往重写toString方法,用于返回对象的属性信息
2)重写toString方法,打印对象或拼接对象时,都会自动调用该对象的toString形式
3)当直接输出一个对象时,toString方法会被默认的调用,比如System.out.println(monster);就会默认调用monster.toString()
1.3.1 Object的toString()源码
/* * Object的toString()源码 * (1)getClass().getName()类的全类名(包名+类名) * (2)Integer.toHexString(hashCode())将对象的hashCode值转换成16进制字符串 * */ public String toString(){ return getClass().getName() + "@" + Integer.toHexString(hashCode()); } }
1.3.2 重写toString()方法
1 public class ToString_ { 2 public static void main(String[] args) { 3 Monster monster = new Monster("小钻风","巡山的",1000); 4 System.out.println(monster.toString() + "hashCode" + monster.hashCode()); 5 System.out.println("==当直接输出一个对象时,toString方法会被默认调用=="); 6 System.out.println(monster);//等价于monster.toString(); 7 } 8 9 } 10 11 class Monster{ 12 private String name; 13 private String job; 14 private double salary; 15 16 public Monster(String name,String job,double salary){ 17 this.name = name; 18 this.job = job; 19 this.salary = salary; 20 } 21 22 //重写toString方法,输出对象的属性 23 //使用快捷键即可 alt+insert->toString 24 25 @Override 26 public String toString() { //重写后一般是把对象的属性值输出,当然程序员也可以自己定制 27 return "Monster{" + 28 "name='" + name + '\'' + 29 ", job='" + job + '\'' + 30 ", salary=" + salary + 31 '}'; 32 } 33 }
1.4 finalize方法
- 当对象被回收时,系统自动调用该对象的finalize方法。子类可以重写该方法,做一些释放资源的操作
- 什么时候被回收:当某个对象没有任何引用时,则jvm就认为这个对象是一个垃圾对象,就会使用垃圾回收机制来销毁该对象,在销毁对象前,会先调用finalize方法
- 垃圾回收机制调用,是由系统来决定(即有自己的GC算法),也可以通过System.gc()主动触发垃圾回收机制
- 在实际开发中,几乎不会运用finalize,所以更多就是为了应付面试
1 public class Finalize_ { 2 public static void main(String[] args){ 3 Car bmw = new Car("宝马"); 4 //这时car对象就是一个垃圾,垃圾回收器就会回收(销毁)对象,在销毁对象之前,会调用该对象的finalize方法 5 //程序员就可以在finalize中,写自己的业务逻辑代码(比如释放资源:数据库连接,或者打开的文件...) 6 //如果程序员不重写finalize,那么就会调用Object类的finalize,即默认处理 7 bmw = null; 8 System.gc();//主动调用垃圾收集器 9 System.out.println("程序退出了"); 10 } 11 } 12 13 class Car{ 14 private String name; 15 //属性,资源.. 16 public Car(String name){ 17 this.name = name; 18 } 19 20 //重写finalize 21 @Override 22 protected void finalize() throws Throwable{ 23 System.out.println("我们销毁 汽车" + name); 24 System.out.println("释放了某些资源..."); 25 } 26 }