Object 与 Objects

Author Avatar
ahscuml 3月 18, 2018
  • 在其它设备中阅读本文章

看书看到Object,后来又看到了Objects,这两个非常相似,为了更加清晰的找出两者的不同,特地收录进来。

Object(原始Object)

java.lang.Object
所有的class都继承自Object类,这是所有类的父类。

方法

  • clone
  • equals
  • getClass
  • hashCode
  • toString

处理线程时才会被调用:

  • notify
  • notifyAll
  • wait
  • wait(long timeout)
  • wait(long timeout,int nanos)

1. public final Class<?> getClass()
final方法,不允许子类重写
返回当前运行时对象的Class对象(当前程序运行时怎么理解???)

2. public int hashCode()
返回这个对象的哈希值(主要使用在hash table 、 HashMap)
三大定律:

  1. 在java程序执行的过程中,一个对象在没有改变的情况下,无论被调用多少次,哈希码都是不变的(返回相同的整数值)
  2. 如果用equals方法比较两个对象相等,则这两个对象一定返回相同的哈希值
  3. 如果用equals方法比较两个对象不相等,两个对象的哈希值可能相等。但是不同的哈希值可以提高哈希表的性能。
    由于所有类都是继承自Object类的,因此每一个对象都有hashcode方法。通常情况下,不同的对象产生的哈希值不同,因为默认的哈希值是通过hashcode方法导出的对象的存储地址。(那为什么还要重写hashcode方法?,直接用默认的不就可以了????)

3.public boolean equals(Object obj)
比较两个对象是否相等,Object中默认的equals方法相当于比较两个对象的内存地址是否相等。

  • reflexive,自反性。任何非空引用值x,对于x.equals(x)必须返回true
  • symmetric,对称性。任何非空引用值x和y,如果x.equals(y)为true,那么y.equals(x)也必须为true
  • transitive,传递性。任何非空引用值x、y和z,如果x.equals(y)为true并且y.equals(z)为true,那么x.equals(z)也必定为true
  • consistent,一致性。任何非空引用值x和y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改
  • 对于任何非空引用值 x,x.equals(null) 都应返回 false

如果重写equals方法,通常需要重写hashcode方法。
默认的equals方法中,如果两个非空引用值引用同一个对象,则equals方法返回true。

较完美重写equals方法(Object类中,与Objects类不同):

假定传入参数为otherObject。

  1. 首先检查this与otherObject是否引用同一个对象。
    if (this == otherObject) return true;
    这是一个优化,也是一种常用的形式。因为计算这个等式的代价要比一个一个比较类中的域付出的代价小得多。
  2. 检查otherObject是否为null,是则为false,这个检查很有必要。
    if (otherObject == null) return false;
  3. 比较this和otherObject是否属于同一个类。如果equals语义在每个子类中有所改变(由子类决定相等的概念),就使用getClass检测。
    if (getClass != otherObject.getClass()) return false;
    如果所有子类都拥有统一的语义(由超类决定相等的概念),就使用instanceof()检测。
    if (!(otherObject instanceof ClassName)) return false;
  4. 将otherObject转化为相应的类类型变量。
    ClassName other = (ClassName) otherObject
  5. 使用==比较基本类型域,使用equals比较对象域。如果所有的域都匹配,则返回true,否则返回false。
    return field1 == other.field1 && field2.equals(other.field2) && …
    如果在子类中重新定义equals,就要在其中包含调用super.equals(other)

4. protected Object clone() throws CloneNotSupportedException
创建并返当前对象的一份拷贝
通常情况下 x.clone() != x 会是真; clone().getClass() == x.getClass() 也会是真;同时 x.clone().equals(x) 也会是真。
Object本身没有实现Cloneable接口,所以如果没有直接重写的话会产生错误(CloneNotSupportedException)。
如果要使用Clone方法需要继承Cloneable接口,同时重写Clone方法,通常是super.clone()
例:

 @Override
public Object clone() throws  CloneNotSupportedException{
Father father = (Father)super.clone();
return father;
}

同时还要注意深复制和浅复制的问题。
还没有解决的问题,关于数组的方法 对于数组而言,clone方法都是浅复制方法。

5.public String toString()
返回表时对象值得字符串

public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

例如原生toString方法:

Clone.Father@677327b6  

官方推荐所有的Object子类都重写toString方法。

Objects(继承自Object)

java.util.Objects

  1. 全部是静态方法
  2. 在计算hash code,返回字符串,比较两个object时,包括了null 的安全方法(不用验证null)

This blog is under a CC BY-NC-SA 4.0 Unported License
本文链接:https://ahscuml.github.io/Objects与Object/