1、Object的使用
- 含义:所有类的基类/超类
- 理解:一个类没有明确继承的父类,都默认继承Object类,所以Object是所有类的祖先类
Object四个常用方法:
equals():比较两个对象内存地址是否相同
getClass():获取该类的class对象
hashCode():获取该对象的hash码(注意:hash码是内存地址+散列算法算出来的一个int值,hash码不等于内存地址)
toString():返回对象的字符串表现形式(将对象转换为字符串)
1、equals():比较两个对象内存地址是否相同
//基本数据类型使用==,比较的是两个变量里的值是否相同 int a = 10; int b = 20; System.out.println(a == b);//false //引用数据类型使用==,比较的是两个对象里的内存地址是否相同 Object obj1 = new Object();//0x001 Object obj2 = new Object();//0x002 System.out.println(obj1 == obj2);//false System.out.println(obj1.equals(obj2));//false
equals()底层代码:
public boolean equals(Object obj){ obj1 == obj2 return (this == obj); }
2、getClass():获取该类的class文件对象
前言:
使用到一个类,如果这个类没有加载到方法区时,就会加载。
JVM会将该类的class文件加载到方法区,在堆中创建该类的class文件的对象(简称class对象),
class对象作为该类class文件的访问入口。
类的class文件只加载一次,所以该类的class对象只有一个//获取Object类的class对象 Class<? extends Object> class1 = obj1.getClass(); Class<? extends Object> class2 = obj2.getClass(); System.out.println(class1 == class2);//true,因为JVM加载class文件时会创建class文件的对象,且类的class文件只加载一次,所以该类的class对象只有一个,所以地址相同 System.out.println("获取该类的全限定名:" + class1.getName());//全限定名(包名加类名):java.lang.Object //获取该类所有的方法(思想:万物皆对象,一个属性是一个属性对象,一个方法是一个方法对象)——反射思想 Method[] methods = class1.getDeclaredMethods(); for (Method method : methods) { System.out.println(method); }
3、hashCode():获取该对象的hash码
Object obj1 = new Object(); System.out.println(obj1.hashCode());
4、toString():返回对象的字符串表现形式(将对象转换为字符串)
注意:打印对象,默认调用toString()System.out.println(obj1);//java.lang.Object@15db9742 System.out.println(obj2.toString());//java.lang.Object@6d06d69c
toString()的底层代码 :
public String toString(){ return getClass().getName() + "@" + Integer.toHexString(hashCode()); } //getClass().getName() -> this.getClass().getName() -> obj2.getClass().getName() //理解:获取class对象,再获取类的全限定名 -- java.lang.Object //Integer.toHexString(hashCode()) -> Integer.toHexString(this.hashCode()); -> Integer.toHexString(obj2.hashCode()); //理解:获取对象的hash值,再将十进制的hash值转换为十六进制的hash值 -- 6d06d69c
2、重写Object的equals()和toString()
Object - equals():比较两个对象是否相同,不同的子类有着不同的比较规则,所以子类重写即可
Object - toString():获取对象的字符串表示,不同的子类有着不同的数据,所以子类重写即可
equals()重写: User user1 = new User("1445584980", "123123", "何老师", 2000);//0x001 User user2 = new User("1445584980", "123123", "何老师", 2000);//0x002 //1、 自动转型:equals方法的参数类型是Object,user2类型是User,这叫做引用数据类型的向上转型(子类类型转父类类型 - 自动转型) System.out.println(user1.equals(user2));//调用重写后的equals()方法,比较两个对象是否相同,结果为true。如果用的是Object的的equals()方法,是比较内存地址是否相同,结果为false。 System.out.println(user1); System.out.println(user2);//注意:打印对象,默认调用toString()
重写后的equals()方法: @Override public boolean equals(Object obj) { if(this == obj){//比较地址是否相同 return true; } //2、强制转型:obj是Object类型,user是User类型,这叫做引用数据类型的向下转型(父类类型转子类类型 - 强制转型) User user = (User) obj; if(this.username.equals(user.username)){//这里的equals()是String类里重写的,是判断两个字符串内容是否相同,即判断username是否相同。Object的的equals()方法是比较内存地址是否相同。 return true; } return false; }
重写后的toString()方法: @Override public String toString() { return username + " -- " + password + " -- " + money; }//注意:打印对象,默认调用toString()
3、String重写的equals和 toString()
String的equals是重写了的,判断两个字符串内容是否相同
@Override //String的equals是重写了的,判断两个字符串内容是否相同,以下是String的equals是重写代码 public boolean equals(Object obj) { if(this == obj){ return true; } MyString m = (MyString) obj; char[] v1 = this.value; char[] v2 = m.value; if(v1.length != v2.length){ return false; } for (int i = 0; i < v1.length; i++) { if(v1[i] != v2[i]){ return false; } } return true; }
重写toString():
@Override public String toString() { String str = ""; for (char c : value) { str += c;//字符串拼接“+” } return str; }