java的object类

object类

看下object类的结构:
java的object类_第1张图片

Object是所有类的父类,任何类都默认继承Object。在Java中,如果没有指定父类,则默认为Object。这是因为Object类是Java中最基本的类,也是所有类的祖先

  1. public String toString()
    : 这个方法返回对象的字符串表示形式。通常,在打印对象时会调用此方法。默认实现返回对象的类名和哈希码的无符号十六进制表示形式。
  2. public boolean equals(Object obj)
    : 这个方法用于比较两个对象是否相等。根据 obj 的类型,它会执行类型转换并使用 equals() 方法比较对象的内容。如果两个对象相等,则返回 true;否则返回 false。
  3. public int hashCode()
    : 这个方法返回对象的哈希码值。哈希码是一个整数,代表了该对象在内存中的存储位置,它是根据对象的内容计算得出的。如果两个对象相等(即 equals() 方法返回 true),则它们的哈希码必须相等。
    hashcode存在主要是为了查找的快捷性,hashcode是用来在散列存储结构中确定对象的存储地址的。
  4. protected Object clone() throws CloneNotSupportedException
    : 这个方法创建并返回此对象的一个副本。如果对象所属的类不支持克隆,将抛出 CloneNotSupportedException 异常。
  5. public final Class getClass()
    : 这个方法返回对象的运行时类。运行时类是对象所属的实际类的类对象。
  6. public final void notify()
    : 这个方法唤醒在此对象监视器上等待的单个线程。如果没有线程在等待,则什么也不做。
  7. public final void notifyAll()
    : 这个方法唤醒在此对象监视器上等待的所有线程。
  8. public final void wait()
    : 这个方法导致当前线程等待,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
  9. public final void wait(long timeout)
    : 这个方法导致当前线程等待指定的时间(以毫秒为单位)。如果在指定的时间内没有其他线程调用此对象的 notify() 方法或 notifyAll() 方法,则返回。
  10. public final void wait(long timeout, int nanos)
    : 这个方法与 wait(long timeout) 类似,但接受纳秒作为参数,以便更精确地控制等待时间。
  11. public final boolean instanceof(Class cls)
    : 这个方法检查此对象是否是指定类的实例。如果是,则返回 true;否则返回 false。

一些问题和解决方案

  1. 为什么重写equals同时也要重写hashcode方法?
    Java中规定,如果两个对象相等(即equals方法返回true),那么它们的hashCode值也必须相同。如果不重写hashCode方法,那么默认情况下,每个对象的hashCode值都由其内存地址决定,这样不同的对象就有可能产生相同的hashCode值,导致在使用哈希表等数据结构时出现错误。
    因此,在重写equals方法时,也应该同时重写hashCode方法,以保证相等的对象具有相同的哈希码值,从而保证在使用哈希表等数据结构时的正确性。
  2. 怎么写hashcode?
    在 JDK 的 Integer类,Float 类,String 类等都重写了 hashCode 方法,我们自定义对象也可以参考这些类来写。比如StringLatin1的hashcode:
public static int hashCode(byte[] value) {
        int h = 0;
        for (byte v : value) {
            h = 31 * h + (v & 0xff);
        }
        return h;
    }

Integer 的hashcode:

  public static int hashCode(int value) {
        return value;
    }

比较省事的重写 hashCode 方法就是用别人的轮子

public int hashCode() {
        int result = 31*declaringClass.hashCode() + methodName.hashCode();
        result = 31*result + Objects.hashCode(classLoaderName);
        result = 31*result + Objects.hashCode(moduleName);
        result = 31*result + Objects.hashCode(moduleVersion);
        result = 31*result + Objects.hashCode(fileName);
        result = 31*result + lineNumber;
        return result;
    }

public int hashCode() {
    return Arrays.hashCode(this.ptypes);
}
  1. 为什么 String hashCode 方法选择数字31作为乘数?
    值 31 被选择是因为它是一个奇素数。如果它是偶数并且乘法溢出,信息将会丢失,因为乘以 2 相当于移位。使用素数的优势不太明显,但它是传统的。31 的一个很好的性质是,乘法可以用移位和减法来替换以获得更好的性能:31 * i == (i << 5) - i 。现代虚拟机会自动进行这种优化。
  2. equals和 == 的区别
    == 是比较运算符,用于比较两个基本数据类型或两个对象是否相等。对于基本数据类型,它比较的是值;对于对象,它比较的是地址
    而equals()是一个方法,只能比较引用数据类型。如果对象没有覆盖equals方法,那么等价于 == 。如果对象覆盖了equals方法,则根据覆盖的equals具体实现来判断。一般是比较对象内容 。

你可能感兴趣的:(java,开发语言)