浅解java中的Object类

综述

Object类位于java核心包java.lang下,是所有Java类的祖先类,内部包含了13个方法。
首先来看看源码中对Object中是如何解释的:
在这里插入图片描述
从图中可知在java的继承结构中,Object位于最顶层。Object类是所有类的超类(直接父类或非直接父类),通常不需要显式的用"extends"关键字进行标明。源码中还注释“所有的对象,包括数组(数组也是对象)都实现这个类的方法”,当然根据继承的机制,这里的方法是指非私有的方法。那么就有必要了解一下Object 中都有那些方法以及他们都具有怎样的作用。

Object类中方法

在这里插入图片描述

1.Object()

Object类的构造方法,作用就是构造一个新的Object对象。我们知道所有子类的构造函数默认第一行都有句super(),作用就是调用父类的构造方法以保证正确的初始化。Object类是所有类的超类,故而所有类使用构造方法进行创建的过程中都会调用到这个Object()方法。

2.registerNatives()

关于这个方法的源码如下

 private static native void registerNatives();
    static {
        registerNatives();
    }

由此可以看出这是一个私有的,静态的,本地方方法。它不会被继承且在Object类加载的时候就会被初始化调用(在静态代码块中被调用)。关于这个方法的作用可以参考下面这篇文章:(点击超链接即可跳转)

Object类中的registerNatives方法的作用深入介绍

大概意思就是:注册本类中所包含的除了registerNatives()方法以外的所有本地方法,使我们的java程序能够更好的直接调用本地方法。

3.getClass()

源码:

 @HotSpotIntrinsicCandidate
    public final native Class<?> getClass();

@HotSpotIntrinsicCandidate注解:Java 9引入的新特性被@HotSpotIntrinsicCandidate标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。
public修饰:公共的方法,对所有的类可见,可以被子类继承
final修饰:不允许子类重写
返回值类型:实际的结果类型是Class<? extends |X|> ,其中|X|是被称为getClass的表达式的静态类型的擦除

作用:返回此对象(方法的调用者)的运行时类(Class对象)。 返回的Class对象是被表示类的static synchronized方法锁定的对象。

4.hashCode()

源码:

 public native int hashCode()

@HotSpotIntrinsicCandidate注解:Java 9引入的新特性被@HotSpotIntrinsicCandidate标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。
public修饰:公共的方法,对所有的类可见,可以被子类继承
native修饰:本地方法,只声明接口,通过系统方法实现
此方法没有final修饰,说明可以在子类中对其进行重写
返回值类型:Int型,返回一个整数

作用:获取对象的哈希码值(hashCode),hashCode就是根据对象的地址或者字符串或者数字算出来的int类型的数值。

  • 无论何时在执行Java应用程序时多次调用同一对象,hashCode方法必须始终返回相同的整数。
  • 如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。

5.equals(Object obj)

源码:


    public boolean equals(Object obj) {
        return (this == obj);
    }

public修饰:公共的方法,对所有的类可见,可以被子类继承
此方法没有final修饰,说明可以在子类中对其进行重写
参数类型:Object,也就是指所有引用类型
返回值类型:boolean型,返回一个布尔值

作用:指示一些其他对象(参数对象)是否等于this对象(该方法的调用,者)

由源码可知如果不重写此方法,则默认使用"=="进行比较,这种方式下比较的是对象的地址,也就是说equals()默认比较对象的地址。如果我们只需要比较对象的内容而不在乎二者到底是不是同一个对象时,那么就需要在子类中重写该方法。

一般情况下如果我们要比较两个对象是否为同一个对象,我们会直接使用""==关系运算符。所以我们一般都会对equals方法进行重写以满足我们只比较对象内容的需要。

6.clone()

源码:

 @HotSpotIntrinsicCandidate
    protected native Object clone() throws CloneNotSupportedException;

@HotSpotIntrinsicCandidate注解:Java 9引入的新特性被@HotSpotIntrinsicCandidate标注的方法,在HotSpot中都有一套高效的实现,该高效实现基于CPU指令,运行时,HotSpot维护的高效实现会替代JDK的源码实现,从而获得更高的效率。
protected修饰:受保护的方法,可以被子类继承
native修饰:本地方法,只声明接口,通过系统方法实现
此方法没有final修饰,说明可以在子类中对其进行重写
返回值类型:Object类型
异常 :CloneNotSupportedException 对象的类不支持Cloneable接口,无法克隆(Cloneable接口是一个标识接口,只有实现了该接口的类)

作用:克隆,即创建并返回此对象的副本(完全一个全新的对象)

具体使用参考如下文章:(点击链接查看)

JAVA 中的的clone()详解

7.toString()

源码:

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

public修饰:公共的方法,可以被子类继承
此方法没有final修饰,说明可以在子类中对其进行重写
返回值类型:String类型

作用:返回对象的字符串表示形式

  • 使用 System.out.println(对象)打印的就是这个对象的toString()方法输出的字符串。
  • 由源码可知toString方法默认输出"类名"和"@"和"hashCode"的字符串形式(以十六进制(基数16)无符号整数形式表示的long类型数据
    的字符串表示形式)拼接而成的字符串。
  • 建议所有子类重写此方法,使输出更为清晰明确的表示一个对象,如可以把内容书写成 “属性=属性值,属性=属性”值的表示形式。

8. notify()

源码:

 @HotSpotIntrinsicCandidate
    public final native void notify();

public final native修饰的方法,允许子类继承但不允许子类对其重写的本地方法。作用是随机唤醒和当前线程处于同一个锁或同步监视器下的等待队列中的一条线程。

9. notifyAll()

源码:

 @HotSpotIntrinsicCandidate
    public final native void notifyAll();

public final native修饰的方法,允许子类继承但不允许子类对其重写的本地方法。作用是唤醒和当前线程处于同一个锁或同步监视器下的等待队列中的所有线程。

10. wait(long timeout)

源码:

public final native void wait(long timeout) throws InterruptedException;

public final native修饰的方法,允许子类继承但不允许子类对其重写的本地方法。作用是使当前线程释放锁并等待,直到其他线程调用此对象的 notify() 方法或notifyAll()方法,或在已经过去 指定timeout的时间,如果timeout的值为0,则表示这个时间无效,线程在被唤醒或中断之前将一直等待。

进入等待的线程,如何才能脱落等待状态:
1.其他线程调用对象的notify()方法并且恰好T成为被随意选中的唤醒线程。
2.其他线程调用对象的notifyAll()方法。
3.其他线程打断
4.指定的休眠时间已经过去,或多或少。如果timeout为零,那么休眠时间将不再生效,只会简单的等待直到被唤醒。

11. wait(long timeout, int nanos)

源码:

  public final void wait(long timeout, int nanos) throws InterruptedException {
        if (timeout < 0) {
            throw new IllegalArgumentException("timeout value is negative");
        }

        if (nanos < 0 || nanos > 999999) {
            throw new IllegalArgumentException(
                                "nanosecond timeout value out of range");
        }

        if (nanos > 0) {
            timeout++;
        }

        wait(timeout);
    }

public修饰:公共的方法,可以被子类继承
此方法使用final修饰,不允许子类对其进行重写

参数timeout:最大等待时间(毫秒)
参数nanos:附加时间在毫秒范围(0-999999)

作用:使当前线程等待,直到其他线程调用此对象的 notify() 方法或notifyAll()方法,或在指定已经过去的时间。它允许更好地控制的时间等待一个通知放弃之前的量。实时量,以毫微秒计算,计算公式如下:
1000000 * timeout + nanos
在所有其他方面,这种方法与 wait(long timeout) 做同样的事情。特别是 wait(0, 0) 表示和 wait(0) 相同

12. wait()

源码:

   public final void wait() throws InterruptedException {
        wait(0);
    }

public final修饰的方法,允许子类继承但不允许子类对其进行重写。作用是使当前线程释放锁并进入等待,在未被唤醒或中断前将一直处于等待状态。

13. finalize()

源码:

 @Deprecated(since="9")
    protected void finalize() throws Throwable { }

@Deprecated(since=“9”):该注解标注的内容,表示已过时 以过时方法,不建议使用
protected修饰:受保护的方法,对所有的类可见,可以被子类继承
返回值类型:void
异常:Throwable,Error和Exception的父类,表示所有可以抛出的异常。
可以在子类中对其进行重写

作用:
下面摘抄网友对该方法的两段解释:

  1. finalize是在对象回收前做一些清扫工作,以及可清理栈上的内存,比如调用本地方法可能在栈上创建对象。即使对象不可达,也并不是非死不可,还是可以抢救一下,当一个对象没有与GCroot相连的引用链时,它将被第一次标记,然后判断对象是否有必要执行finalize()方法。当对象没有覆盖finalize()方法(没有就没法抢救了),或者finalize()方法已经被虚拟机调用过,则不必执行,如果有必要执行,该对象就会被放到一个叫做F-Queue的队列里,并且由一个低优先级的Finalizer线程去执行它。但是不保证会等待方法执行结束。finalize方法是对象逃脱的最后机会,稍后GC会对F-Queue中的对象进行二次标记,只要对象重新链接上了引用链,它就会被移出即将回收的集合。
  2. 我们知道java有垃圾回收器负责回收无用对象占据的内存资源,但也有特殊情况:假设你的对象(并非使用new)获得了一块特殊的内存区域,由于垃圾回收器只知道回收那些经由new分配的内存,所以它不知道如何释放该对象的这块特殊的内存。为了应对这种特殊情况,java允许在类中定义一个名为finalize()的方法。它的工作原理假定是这样的:一旦垃圾收集器准备释放对象占用的存储空间,将首先调用其finalize()方法,并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存,所以如果你打算用finalize()。

我的理解就是:
finallize()方法在对象被回收的时候被调用(就好像垃圾收集器对对这个对象说:我要杀死你了,你还有什么事情要做或什么话要说吗,可以通过finalize()告诉我),基于此原理,我们可以重写该方法并在该方法中重新建立引用联系(如此可以避免被回收)或者完成一些被回收前的检测工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值