02、
在 Java 中,所有类都由 Object 类继承而来。Object 这个单词的英文意思是对象,是不是突然感觉顿悟了——万物皆对象?没错,Java 的设计者真是良苦用心了啊!现在,你一定明白了为什么 Java 是面向对象编程语言的原因。
你可能会疑惑地反问道:“我的类明明没有继承 Object 类啊?”如果一个类没用显式地继承某一个类,那么它就会隐式地继承 Object 类。换句话说,不管是鸡生了蛋,还是蛋孵出了鸡,总有一只 Object 鸡或者一个 Object 蛋。
在面试的时候,你可能会被问到这么一个问题:“Object 类包含了哪些方法呢?”
1)protected Object clone() throws CloneNotSupportedException 创建并返回此对象的副本。
不过,《阿里巴巴 Java 开发手册》上建议:慎用 Object 的 clone 方法来拷贝对象。因为 Object 的 clone 方法默认是浅拷贝,如果想实现深拷贝需要重写 clone 方法实现属性对象的拷贝。
什么是浅拷贝,什么是深拷贝呢?
浅拷贝是指在拷贝对象时,会对基本数据类型的变量重新复制一份,而对于引用类型的变量只拷贝了引用,并没有对引用指向的对象进行拷贝。
深拷贝是指在拷贝对象时,同时对引用指向的对象进行拷贝。
浅拷贝和深拷贝的区别就在于是否拷贝了对象中的引用变量所指向的对象。
2)public boolean equals(Object obj) 判断另一对象与此对象是否「相等」。
该方法使用的区分度最高的“==”操作符进行判断,所以只要两个对象不是同一个对象,那么 equals() 方法一定返回 false。
《阿里巴巴 Java 开发手册》上强调:由于 Object 的 equals 方法容易抛出空指针异常,所以应该使用常量或者确定不为 null 的对象来调用 equals。
正例:"test".equals(object);object.equals("test");
在正式的开发项目当中,最经常使用该方法进行判断的就是字符串。不过,建议使用org.apache.commons.lang3.StringUtils,不用担心出现空指针异常。具体使用情况如下所示:
StringUtils.equals(null, null) = true
StringUtils.equals(null, "abc") = false
StringUtils.equals("abc", null) = false
StringUtils.equals("abc", "abc") = true
StringUtils.equals("abc", "ABC") = false
3)public native int hashCode() 返回此对象的哈希码。hashCode() 是一个 native 方法,而且返回值类型是整形;实际上,该方法将对象在内存中的地址作为哈希码返回,可以保证不同对象的返回值不同。
A native method is a Java method whose implementation is provided by non-java code.native 方法是一个 Java 调用非 Java 代码的接口。该方法的实现由非 Java 语言实现,比如 C。这个特征并非 Java 所特有,其它的编程语言也有这个机制,比如 C++。
hashCode() 通常在哈希表中起作用,比如 HashMap。
向哈希表中添加 Object 时,首先调用 hashCode() 方法计算 Object 的哈希码,通过哈希码可以直接定位 Object 在哈希表中的位置。如果该位置没有对象,可以直接将 Object 插入该位置;如果该位置有对象,则调用 equals() 方法比较这个对象与 Object 是否相等,如果相等,则不需要保存 Object;如果不相等,则将该 Object 加入到哈希表中。
4)protected void finalize() throws Throwable 当垃圾回收机制确定该对象不再被调用时,垃圾回收器会调用此方法。不过,fnalize 机制现在已经不被推荐使用,并且在 JDK 9 开始被标记为 deprecated(过时的)。
5)public final Class getClass() 返回此对象的运行时类。
当我们想知道一个类本身的一些信息(比如说类名),该怎么办呢?这时候就需要用到 Class 类,该类包含了与类有关的信息。请看以下代码:
Wanger wanger = new Wanger();
Class c1 = wanger.getClass();
System.out.println(c1.getName());
// 输出 Wanger
6)public String toString() 返回此对象的字符串表示形式。
《阿里巴巴 Java 开发手册》强制规定:POJO 类必须重写 toString 方法;可以使用 Eclipse 直接生成,点击 「Source」→「Generate toString」。示例如下:
class Wanger {
private Integer age;
@Override
public String toString() {
return "Wanger [age=" + age + "]";
}
}
重写 toString() 有什么好处呢?当方法在执行过程中抛出异常时,可以直接调用 POJO 的 toString() 方法打印其属性值,便于排查问题。
POJO(Plain Ordinary Java Object)指简单的 Java 对象,也就是普通的 JavaBeans,包含一些成员变量及其 getter / setter ,没有业务逻辑。有时叫做 VO (value - object),有时叫做 DAO (Data Transform Object)。
03、
本篇,我们先谈了面向对象的重要特征继承;然后谈到了继承的终极父类 Object!