Java学习打卡-Day10

学习自JavaGuide

Object类的常见方法

  • Object 类是所有类的父类,主要提供了以下 11 个方法:
    /**
     * native 方法,用于返回当前运行时对象的 Class 对象,使用了 final 关键字修饰,故不允许子类重写。
     */
    public final native Class<?> getClass()
    
    /**
     * native 方法,用于返回对象的哈希码,主要使用在哈希表中,比如 JDK 中的HashMap。
     */
    public native int hashCode()
    
    /**
     * 用于比较 2 个对象的内存地址是否相等,String 类对该方法进行了重写以用于比较字符串的值是否相等。
     */
    public boolean equals(Object obj)
    
    /**
     * native 方法,用于创建并返回当前对象的一份拷贝。
     */
    protected native Object clone() throws CloneNotSupportedException
    
    /**
     * 返回类的名字实例的哈希码的 16 进制的字符串。建议 Object 所有的子类都重写这个方法。
     */
    public String toString()
    
    /**
     * native 方法,并且不能重写。唤醒一个在此对象监视器上等待的线程(监视器相当于就是锁的概念)。如果有多个线程在等待只会任意唤醒一个。
     */
    public final native void notify()
    
    /**
     * native 方法,并且不能重写。跟 notify 一样,唯一的区别就是会唤醒在此对象监视器上等待的所有线程,而不是一个线程。
     */
    public final native void notifyAll()
    
    /**
     * native方法,并且不能重写。暂停线程的执行。注意:sleep 方法没有释放锁,而 wait 方法释放了锁 ,timeout 是等待时间。
     */
    public final native void wait(long timeout) throws InterruptedException
    
    /**
     * 多了 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。
     */
    public final void wait(long timeout, int nanos) throws InterruptedException
    
    /**
     * 跟之前的2个wait方法一样,只不过该方法一直等待,没有超时时间这个概念
     */
    public final void wait() throws InterruptedException
    
    /**
     * 实例被垃圾回收器回收的时候触发的操作
     */
    protected void finalize() throws Throwable { }
    

hashCode()

有什么用?

  • hashCode() 的作用是获取哈希码(int 整数),也称为散列码。这个哈希码的作用是确定该对象在哈希表中的索引位置。

为什么需要 hashCode()?

当把对象加入 HashSet 时,HashSet 会先计算对象的 hashCode 值来判断对象加入的位置,同时也会与其他已经加入的对象的hashCode 值作比较,如果没有相符的hashCode,HashSet 会假设对象没有重复出现。但是如果发现有相同 hashCode值的对象,这时会调用 equals() 方法来检查 hashCode 相等的对象是否真的相同。如果两者相同,HashSet就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样我们就大大减少了 equals()的次数,相应就大大提高了执行速度。

为什么JDK同时提供 hashCode() 和 equals() 方法?

  • hashCode() 和 equals() 都是用于比较两个对象是否相等。
  • 在一些容器(比如 HashMap、HashSet)中,有了 hashCode() 之后,判断元素是否在对应容器中的效率会更高。
  • 前面提到添加元素进HashSet的过程,如果 HashSet 在对比的时候,同样的 hashCode 有多个对象,它会继续使用 equals() 来判断是否真的相同。也就是说 hashCode() 帮助我们大大缩小了查找成本。
  • 为什么不只提供 hashCode() 方法呢?
    • 这是因为两个对象的 hashCode 值相等并不代表两个对象就相等。
  • 这又是为什么呢?
    • 因为 hashCode() 所使用的哈希算法也许刚好会让多个对象传回相同的哈希值。越糟糕的哈希算法越容易碰撞,但这也与数据值域分布的特性有关(所谓哈希碰撞也就是指的是不同的对象得到相同的 hashCode )。

为什么重写 equals() 方法必须重写 hashCode() 方法?

  • 两个相等对象的 hashCode 值必须相等。也就是说如果 equals() 方法判断两个对象是相等的,那这两个对象的 hashCode 值也要相等
  • 如果重写 equals() 时没有重写 hashCode() 方法的话就可能会导致 equals 方法判断是相等的两个对象,hashCode 值却不相等

String 的实例化方式

  • 方法1:通过字面量的方法,也就是直接给所定义的字符串赋值。
    • 当使用双引号创建一个字符串时,会存储到字符串常量池,且相同内容的字符串只存储一份。节省了大量的内存。
  • 方法2:通过 new + 构造器 的方法。
    • 通过 new 方式创建字符串对象,每new一次都会产生一个新的对象放在堆内存中

类的五大成分

  • 成员变量
  • 构造器
  • 方法
  • 代码块
  • 内部类

1、成员变量

  • 普通成员变量/实例成员变量/属性/字段:没有特殊关键字修饰;
  • 静态成员变量:由 static 修饰;
  • (常量:由 static 和 final 修饰。)

2、构造器

  • 没有返回值,支持重载。
  • 每个类都有默认无参的空构造方法,如果自定义了带参数的构造方法,无参的空构造方法会失效。

3、方法

  • 实例方法:属于对象,需要通过创建对象的实例来调用。
  • 静态方法:属于类本身,可以直接通过类名调用,无需创建对象的实例。

4、代码块

  • 实例代码块
    • 格式:{}
    • 特点:每次创建对象时执行,且是在构造器之前执行
    • 作用:统一初始化对象的实例资源。对于数组很方便。
  • 静态代码块
    • 格式:static{}
    • 特点:类加载时自动执行,由于类只会加载一次,静态代码块也只会执行一次。
    • 作用:可以完成对类静态资源的初始化,例如对静态成员变量的初始化。对于数组很方便。

5、内部类

  • 定义在一个类的内部的类。
  • 成员内部类
    • 由外部类的对象持有,就是外部类的一个成员,地位类似于普通成员变量,成员方法。
    • 如何创建对象:Outer.Inner oi = new Outer().new Inner();
    • 成员内部类可以直接访问外部类的静态成员/方法,也可以直接访问外部类的实例成员/方法
    • 成员内部类可以直接拿到当前寄生的外部类对象外部类名.this
  • 静态内部类
    • 由 static 修饰,由外部类自身持有。
    • 如何创建对象:Outer.Inner oi = new Outer.Inner();
    • 静态内部类可以直接访问外部类的静态成员/方法,不可以访问外部类的实例成员/方法
  • 局部内部类:定义在方法、代码块、构造器等中的类。
  • 匿名内部类
    • 下回分解······

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