Object类源码(所有方法分析)|相关(Native方法|Class对象|equals&==|浅拷贝深拷贝)

14 篇文章 0 订阅


所有的方法:


registerNatives()

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

这段代码是当类加载时执行的静态代码块进行本地方法注册
registerNatives()注册Object类除了registerNatives()方法以外的本地方法。
本地方法是平台相关的,本地方法有变,会调用这个方法更新。
直接执行本地方法代码,不需要JVM去定位,通过这个方法主动关联动态连接库中的方法实现。


Native方法

Java方法是平台无关的,JVM加载字节码运行。
本地方法在Java类中定义,用native进行修饰,且只有方法定义,没用方法实现。本地方法是由其他语言编写,编译成处理器相关的机器代码,并保存在动态连接库中,Java类不需要实现这些方法。当Java程序调用本地方法时,JVM通过加载本地方法的动态连接库,找到对应方法并执行相关代码。

【Java方法 本地方法】


java方法:java语言编写,编译成字节码,存储在class文件中,与平台无关。

本地方法:由其他语言(如C、C++ 或其他汇编语言)编写,编译成和处理器相关的代码。本地方法保存在动态连接库中,格式是各个平台专用的。运行中的java程序调用本地方法时,虚拟机装载包含这个本地方法的动态库,并调用这个方法。


通过本地方法,java程序可以直接访问底层操作系统的资源,但是这么用的话,程序就变成了平台相关了。

java的本地方法接口JNI,使得本地方法可以在特定主机系统上的任何一个java平台上实现运行。如果希望使用特定主机上的资源,而他们又无法从JAVA API访问,那么可以写一个平台相关的java程序来调用本地资源。如果希望保证平台的无关性,那么只能通过JAVA API 来访问底层系统的资源。


getClass()

    public final native Class<?> getClass();

获取运行时的类型,返回的对象类型是Class类。
Class是反射操作的源头。

获取Class对象

获取Class类的实例化对象在Java之中有三种方式:

//Object的getClass()方法
Date date = new Date();
Class<?> cls = date.getClass();
//在Hibernate上使用
Class<?> cls = java.util.Date.class;
//Class类提供的方法,在系统架构中使用
Class<?> cls = Class.forName("java.util.Date");

hashCode()

注释说的很详细了~

  /**
     * Returns a hash code value for the object. This method is
     * supported for the benefit of hash tables such as those provided by
     * {@link java.util.HashMap}.
     * <p>
     * The general contract of {@code hashCode} is:
     * <ul>
     * <li>Whenever it is invoked on the same object more than once during
     *     an execution of a Java application, the {@code hashCode} method
     *     must consistently return the same integer, provided no information
     *     used in {@code equals} comparisons on the object is modified.
     *     This integer need not remain consistent from one execution of an
     *     application to another execution of the same application.
     * <li>If two objects are equal according to the {@code equals(Object)}
     *     method, then calling the {@code hashCode} method on each of
     *     the two objects must produce the same integer result.
     * <li>It is <em>not</em> required that if two objects are unequal
     *     according to the {@link java.lang.Object#equals(java.lang.Object)}
     *     method, then calling the {@code hashCode} method on each of the
     *     two objects must produce distinct integer results.  However, the
     *     programmer should be aware that producing distinct integer results
     *     for unequal objects may improve the performance of hash tables.
     * </ul>
     * <p>
     * As much as is reasonably practical, the hashCode method defined by
     * class {@code Object} does return distinct integers for distinct
     * objects. (This is typically implemented by converting the internal
     * address of the object into an integer, but this implementation
     * technique is not required by the
     * Java&trade; programming language.)
     *
     * @return  a hash code value for this object.
     * @see     java.lang.Object#equals(java.lang.Object)
     * @see     java.lang.System#identityHashCode
     */
    public native int hashCode();

返回对象的哈希码值。 支持这种方法有利于哈希表,如HashMap提供的那样 。

  • 无论何时在执行Java应用程序时多次调用同一对象, hashCode方法必须始终返回相同的整数,前提是修改了对象中equals比较中的信息。 该整数不需要从一个应用程序的执行到相同应用程序的另一个执行保持一致。
  • 如果根据equals(Object)方法两个对象相等,则在两个对象中的每个对象上调用hashCode方法必须产生相同的整数结果。
  • 不要求如果两个对象根据equals(java.lang.Object)方法不相等,则在两个对象中的每一个上调用hashCode方法必须产生不同的整数结果。 但是,程序员应该意识到,为不等对象生成不同的整数结果可能会提高哈希表的性能。

equals()


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

指示一些其他对象是否等于此。
equals方法在非空对象引用上实现等价关系:

  • 自反性 :对于任何非空的参考值x , x.equals(x)应该返回true 。
  • 它是对称的 :对于任何非空引用值x和y , x.equals(y)应该返回true当且仅当y.equals(x)回报true 。
  • 传递性 :对于任何非空引用值x , y ,并z ,如果x.equals(y)回报true和y.equals(z)回报true ,然后x.equals(z)应该返回true 。
  • 它是一致的 :对于任何非空参考值x和y ,多重调用x.equals(y)一致返回true或一致返回false ,前提是在equals对对象进行比较的信息被修改。
  • 对于任何非空的参考值x , x.equals(null)应该返回false 。

该equals类方法Object实现对象上差别可能性最大的相等关系; 也就是说,对于任何非空参考值x和y ,当且仅当x和y引用相同对象( x == y具有值true )时,该方法返回true 。

请注意,无论何时覆盖此方法,通常需要覆盖hashCode方法,以便维护hashCode方法的一般合同,该方法规定相等的对象必须具有相等的哈希码。

equals和==

准确的说是String类重写了equals,所以不是直接= =了
而在Object类中equals就是 = =
= = 比较的是两个对象在java虚拟机中的地址;
equals 默认比较的也是两个对象在java虚拟机中的地址,
但是我们可以对一个对象的equals方法进行重写,而“==”我们无法重写;
hashcode 返回一个对象在java虚拟机中的地址;

== :
该操作符生成的是一个boolean结果,
它计算的是操作数的值之间的关系

equals :
Object 的 实例方法,
比较两个对象的content是否相同

hashCode :
Object 的 native方法 , 获取对象的哈希值,
用于确定该对象在哈希表中的索引位置,它实际上是一个int型整数


clone()

	 * @return     a clone of this instance.
     * @throws  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
     * @see java.lang.Cloneable
     */
    protected native Object clone() throws CloneNotSupportedException;

创建并返回此对象的副本。
“复制”的精确含义可能取决于对象的类。 一般意图是,对于任何对象x ,
表达式:
x.clone() != x将是真实的,
而且表达:
x.clone().getClass() == x.getClass()将是true ,但这些都不是绝对的要求。 通常情况是:
x.clone().equals(x)将是true ,这不是一个绝对的要求。

clone对象返回的是一个新对象,而不是一个已有对象的引用。
clone对象与用new操作符返回的新对象是有区别的,clone对象是拷贝某个对象的当前信息,而不是对象的初始信息。


浅拷贝 深拷贝

浅拷贝仅仅复制对象,但不复制对象引用的对象
深拷贝是一个整个独立的对象拷贝,会拷贝所有的属性,并拷贝属性指向动态分配的内存。
深拷贝把要复制的对象所引用的对象都复制了一遍


toString()


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

返回对象的字符串表示形式。 一般来说, toString方法返回一个“ toString代表”这个对象的字符串。 结果应该是一个简明扼要的表达,容易让人阅读。 建议所有子类覆盖此方法。

该toString类方法Object返回一个由类的名称,其中所述对象是其实例,该符号字符`的字符串@ ”,并且对象的哈希码的无符号的十六进制表示。 换句话说,这个方法返回一个等于下列值的字符串:

getClass().getName() + ‘@’ + Integer.toHexString(hashCode())


notify()


    public final native void notify();

唤醒正在等待对象监视器的单个线程。 如果任何线程正在等待这个对象,其中一个被选择被唤醒。 选择是任意的,并且由实施的判断发生。 线程通过调用wait方法之一等待对象的监视器。
唤醒的线程将无法继续,直到当前线程放弃此对象上的锁定为止。 唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步; 例如,唤醒的线程在下一个锁定该对象的线程中没有可靠的权限或缺点。

该方法只能由作为该对象监视器的所有者的线程调用。 线程以三种方式之一成为对象监视器的所有者:

通过执行该对象的同步实例方法。
通过执行在对象上同步的synchronized语句的主体。
对于类型为Class,的对象,通过执行该类的同步静态方法。
一次只能有一个线程可以拥有一个对象的显示器。


notifyAll()


    public final native void notifyAll();

唤醒正在等待对象监视器的所有线程。 线程通过调用其中一个wait方法等待对象的监视器。
唤醒的线程将无法继续,直到当前线程释放该对象上的锁。 唤醒的线程将以通常的方式与任何其他线程竞争,这些线程可能正在积极地竞争在该对象上进行同步; 例如,唤醒的线程在下一个锁定该对象的线程中不会有可靠的特权或缺点。

该方法只能由作为该对象监视器的所有者的线程调用。 有关线程可以成为监视器所有者的方式的描述,请参阅notify方法。


wait() * 3


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

导致当前线程等待,直到另一个线程调用此对象的notify()方法或notifyAll()方法,或者事件已过。

当前的线程必须拥有该对象的显示器。

此方法使当前线程T将其放置在该对象的等待集中,然后放弃对该对象的任何和所有同步声明。线程T禁用线程调度,休眠。


 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);
    }

这种方法类似于一个参数的wait方法,但它允许对放弃之前等待通知的时间进行更精细的控制。 以纳秒为单位的实时数量由下式给出:

1000000*timeout+nanos在所有其他方面,该方法与一个参数的方法wait(long)相同。 特别是wait(0, 0)意味着同样的事情wait(0) 。


/** @throws  IllegalMonitorStateException  if the current thread is not
     *               the owner of the object's monitor.
     * @throws  InterruptedException if any thread interrupted the
     *             current thread before or while the current thread
     *             was waiting for a notification.  The <i>interrupted
     *             status</i> of the current thread is cleared when
     *             this exception is thrown.
     * @see        java.lang.Object#notify()
     * @see        java.lang.Object#notifyAll()
     */
    public final void wait() throws InterruptedException {
        wait(0);
    }

导致当前线程等到另一个线程调用该对象的notify()方法或notifyAll()方法。 换句话说,这个方法的行为就好像简单地执行调用wait(0).


finalize()

    protected void finalize() throws Throwable { }

已过时(Java 9)。 定稿机制本质上是有问题的。 可能导致性能问题,死锁和挂起。 敲定错误可能导致资源泄漏; 如果不再需要,无法取消定稿; 并且在不同对象的finalize方法的调用中没有指定排序。 此外,关于定稿的时间并不保证。 只有在无限期延迟之后,才能在可终止对象上调用finalize方法(如果有的话)。 其实例持有非堆资源的类应提供一种方法来实现这些资源的显式释放,如果适用,它们还应实现AutoCloseable 。 Cleaner和PhantomReference在对象变得不可达时提供更灵活和更有效的方式来释放资源。
当垃圾收集确定不再有对该对象的引用时,垃圾收集器在对象上调用该对象。 一个子类覆盖finalize方法来处理系统资源或执行其他清理。
finalize的一般合同是,如果Java¢虚拟机已经确定不再有任何方法可以由任何尚未死亡的线程访问该对象的方法被调用,除非是由于最后确定的其他对象或类的准备工作所采取的行动。 finalize方法可能会采取任何行动,包括使此对象再次可用于其他线程; 然而, finalize的通常目的是在对象不可撤销地丢弃之前执行清除操作。 例如,表示输入/输出连接的对象的finalize方法可能会在对象被永久丢弃之前执行显式I / O事务来中断连接。

finalize类的finalize方法Object执行特殊操作; 它只是返回正常。 Object子类可以覆盖此定义。

Java编程语言不能保证哪个线程将为任何给定对象调用finalize方法。 但是,确保调用finalize的线程在调用finalize时不会持有任何用户可见的同步锁。 如果finalize方法抛出未捕获的异常,则会忽略该异常,并终止该对象的定类。

在为对象调用了finalize方法之后,在Java虚拟机再次确定不再有任何方法可以使任何尚未死亡的线程访问此对象的任何方法之前,还将采取进一步措施,包括可能的操作由准备完成的其他对象或类别,此时可以丢弃对象。

任何给定对象,Java虚拟机不会多次调用finalize方法。

finalize方法引发的任何异常finalize导致该对象的终止被暂停,否则被忽略。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值