Object类
Object类概述
类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。所有的类都直接或者间接的继承自Object类。该类的设计也符合面向对象中“万事万物皆对象”的思想。
构造方法 :
public Object()
任何一个类都会调用这个方法,访问子类构造方法的首先会先访问父类无参的构造方法。
常用方法
1.int hashCode()
返回该对象的哈希码值。
2.Class<?> getClass()
获取类的路径
3.oolean equals(Object obj)
比较两个对象的地址
4.String toString()
返回的是 类路径 + @ + 对象的hashCode的十六进制转换
5.protected Object clone()
克隆对象
6.protected void finalize()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
方法解析
1.int hashCode()
返回该对象的哈希码值。
返回该对象的哈希码值。支持此方法是为了提高哈希表(例如 java.util.Hashtable 提供的哈希表)的性能。
特点
1.该方法会被哈希表结构利用,哈希表结构会利用这个方法来计算哈希索引值,
从而尽量避免哈希冲突,此方法大部分需要子类重写,此方法的重写是为了提高哈希表的性能 【看完集合的哈希表数据结构以及HashMap底层源码实现后再回过头来看】
2.实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。
(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
3.两个对象如果hashCode相同,不能够完全保证连个对象相同,如果两个对象的hashCode不同,那么两个对象肯定不同
A 0x0001 B 0x0002
A hashCode 12345 B hashCode 12345
4. == 和 equals方法的区别
比较基本数据类型
== 比较的是数值
equals 不可以,这是一个方法
引用数据类型
== 比较的是真实地址
equals 暂时保留
equals 比较 只能够比较引用类型,默认比较的地址,如果重写了一般比较的是内容,具体比较的结果看需求。
代码示例
public class ObjectDemo01 {
public static void main(String[] args) {
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 20);
Student s3 = new Student("张三", 18);
Student s4 = s1;
System.out.println(s1.hashCode()); // 2018699554
System.out.println(s2.hashCode()); // 2018699554
System.out.println(s3.hashCode()); // 118352462
System.out.println(s4.hashCode()); // 2018699554
int a = 10;
int b = 10;
System.out.println(a == b);
System.out.println(s1 == s2);
}
}
2.Class<?> getClass()
万事万物皆对象,利用多个对象的共性来定义 类, 类是用来描述现实世界的事物的,Java当中class来定义类
类用来描述事物,类本身也是一种概念事物,所以Java使用一个类Class来描述 概念事物
class Class {
成员变量对象
成员方法对象
构造方法对象
访问权限修饰符对象
…
}
代码示例
public class ObjectDemo02 {
public static void main(String[] args) {
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 20);
Teacher t = new Teacher();
Class c1 = s1.getClass();
Class c2 = s2.getClass();
Class c3 = t.getClass();
System.out.println(c1);
System.out.println(c1 == c2); // true
System.out.println(c1 == c3); // false
String className = c1.getName();
System.out.println(className); // com.sxt.objectdemo.Student
String className2 = c2.getName();
System.out.println(className2); // com.sxt.objectdemo.Student
System.out.println(t.getClass().getName());
}
}
class Teacher {}
3.oolean equals(Object obj)
该方法默认比较的是连个对象的地址值是否相等。
观察equals的源码:
public boolean equals(Object obj) {
return (this == obj); // s1 == s3
}
比较两个对象比的是地址没有意义,一般判断两个对象是否相等,比较的是对象的成员,所以我们一般自定义对象都需要重写equals方法
如何重写? – 学习String的equals方法
参照String重写equals方法的规则
但是实际开发中一般是自动生成,但是有的时候还是要根据需求来的,通过Eclipse工具快捷键: alt + shift + S 再按H
代码示例
public class ObjectDemo04 {
public static void main(String[] args) {
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 20);
Student s3 = new Student("李四", 20);
Student s5 = new Student(null, 22);
Student s6 = new Student(null, 22);
Student s4 = s1;
System.out.println(s1.equals(s2)); // false
System.out.println(s2.equals(s3)); // true
System.out.println(s1.equals(s4)); // true
// String s = new String("abc");
// String ss = new String("abc");
// System.out.println(s.equals(ss));
System.out.println(s1.equals(new Teacher()));
System.out.println(s1.equals(null));
System.out.println(s5.equals(s6));
UUID randomUUID = UUID.randomUUID();
System.out.println(randomUUID); // 1d0d1b83-1848-479b-b82d-2d3e94288b19
}
}
4.String toString()
输出一个对象默认输出该引用类型的toString方法
观察toString在Object类中的源码
public String toString() {
return this.getClass().getName() + “@” + Integer.toHexString(this.hashCode());
}
默认toString返回的是 类路径 + @ + hashCode值的十六进制
这个字符串对我们来说没有意义,父类Object类中的toString方法不能够满足子类Student的需求,所以需要方法重写
如何来重写? – 一般都是打印对象的成员值
如果一个类中有100个成员,我们都一个一个拼接成员吗? 可以通过Eclipse工具自动生成即可 快捷键: alt + shift + s 再按S
代码示例
public class ObjectDemo03 {
public static void main(String[] args) {
Student s1 = new Student("张三", 18);
Student s2 = new Student("李四", 20);
System.out.println(s1.hashCode()); // 2018699554
String str1 = s1.toString();
String str2 = s2.toString();
System.out.println(str1); // com.sxt.objectdemo.Student@7852e922
System.out.println(str2); // com.sxt.objectdemo.Student@4e25154f
System.out.println(s1.toString());
System.out.println(s1);
Student s3 = null;
System.out.println(s3);
}
}
5.protected Object clone()
该方法表示对对象进行克隆
注意事项:
1.clone方法是protected修饰,子类需要重写,外界才能访问
2.clone的对象必须支持克隆,需要克隆的对象必须实现Cloneable接口
3.多个引用指向同一个堆区空间的问题和克隆的区别
4.深拷贝和浅拷贝
代码示例
public class ObjectDemo05 {
public static void main(String[] args) throws CloneNotSupportedException {
Student s = new Student("张三", 25);
Object obj = s.clone();
// System.out.println(obj);
Student sClone = (Student) obj;
sClone.setName("张三的影子");
sClone.setAge(30);
System.out.println(s);
System.out.println(sClone);
}
}
6.protected void finalize()
当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
子类重写 finalize 方法,以配置系统资源或执行其他清除。
代码示例
public class ObjectDemo06 {
public static void main(String[] args) {
Student s = new Student();
s = null;
// 启动垃圾回收器
System.gc();
// 通知系统的垃圾回收期对象去调用垃圾回收期重写的finalize方法
System.runFinalization();
}
}