Object类是类层次结构的根,每个类都以Object类作为超类,每个对象(包括数组)都实现了Object类的方法。
下面代码是数组实现了Object类方法的例证。
String[] strArr = {"a", "b"};
strArr.hashCode();
strArr.clone();
strArr.equals(strArr);
strArr.toString();
strArr.getClass();
下面是Object类中方法的介绍(以JDK 8 介绍):
1. getClass()
- getClass()由类的实例调用,获取运行时实例的类的Class对象。
- .class由类名调用,获取类的Class对象。
2. equals()、hashCode()
2.1 equals()
==与equals()
- == 判断两个对象的地址是不是相等:如果是基本数据类型,比较的是值;如果是引用数据类型,比较的是内存地址。另外,Integer内部类IntegerCache会缓存[-128,h]的Integer对象(其中h默认为127,可由-XX:AutoBoxCacheMax=设置),在此范围内,==比较时会为同一对象。
Integer integer1 = 100; Integer integer2 = 100; System.out.println(integer1 == integer2); // true Integer integer3 = 300; Integer integer4 = 300; System.out.println(integer3 == integer4); // false Integer integer5 = new Integer(100); Integer integer6 = new Integer(100); System.out.println(integer5 == integer6); // false - equals()判断两个对象是否相等:如果类没有覆写equals(),那么与==作用相同,比较两个对象的地址是不是相等;我们一般通过覆写equals()判断两个对象的内容是不是相等。
public boolean equals(Object obj) { return (this == obj); }
2.3 hashCode()
hashCode()方法的作用:以Set为例,当新加一个对象时,需要判断现有集合中是否已经存在与此对象相等的对象,如果没有hashCode(),需要将Set进行一次遍历,并逐一用equals()判断两个对象是否相等,时间复杂度为O(n),通过hashCode(),可先计算出即将加入的对象的哈希码,根据哈希算法计算此对象的位置,直接判断此位置上是否已有对象。
- 如果两个对象的equals()判断相等,那么这两个对象调用hashCode()返回的哈希码也必须相等。
- 如果两个对象的hashCode()返回的哈希码相等,这两个对象的equals()不一定相等。
- 重写了equals()后,需要重写hashCode()。
3. clone()
clone()实现的是浅拷贝:基本数据类型进行值拷贝,引用数据类型进行引用传递般的拷贝。一个类对象浅拷贝时,需要实现Cloneable接口,调用clone()。
深拷贝:拷贝所有的属性,并拷贝属性指向的动态内存的分配。
实现深拷贝的方式:
-
重写clone(),对内部的引用类型变量,再进行一次拷贝。
@AllArgsConstructor public class Person implements Cloneable { private String name; @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }@AllArgsConstructor public class Animal implements Cloneable { private Person host; private String name; @Override protected Object clone() throws CloneNotSupportedException { Animal animal = (Animal) super.clone(); animal.host = (Person) host.clone(); return animal; } } -
序列化方式实现深拷贝:先将要拷贝对象写入到内存中的字节流中,然后再从字节流中读出刚刚存储的信息,作为一个新对象返回,新对象和原对象不存在任何地址上的共享,自然实现了深拷贝。
@AllArgsConstructor @Data public class Person implements Serializable { private String name; } @AllArgsConstructor @Data public class Animal implements Serializable { private Person host; private String name; } public class CloneUtil { public static <T extends Serializable> T clone(T obj) { T cloneObj = null; try { ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectOutputStream oos = null; oos = new ObjectOutputStream(bos); oos.writeObject(obj); oos.close(); ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); ObjectInputStream ois = new ObjectInputStream(bis); cloneObj = (T) ois.readObject(); ois.close(); return cloneObj; } catch (Exception e) { return null; } } } public class Main { public static void main(String[] args) { Animal animal1 = new Animal(new Person("mustang"), "dog"); Animal animal2 = CloneUtil.clone(animal1); System.out.println(animal1.getHost() == animal2.getHost()); } }
4. toString()
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}