文档章节

【Java部分源码分析之lang篇】1.Object

gongwilliam
 gongwilliam
发布于 2017/07/09 18:48
字数 1228
阅读 14
收藏 0

3 月,跳不动了?>>>

Object是所有Java类的父类,因为在创建Java类的的时候,如果新类没有任何继承类,那么它就继承Object类。这个类就位于Lang包中。先来对它瞥一眼(我已经把多余的英文注释给去掉了)。

package java.lang;

public class Object {

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

    public final native Class<?> getClass();

    public native int hashCode();

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

    protected native Object clone() throws CloneNotSupportedException;

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

    public final native void notify();

    public final native void notifyAll();

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

    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 void wait() throws InterruptedException {
        wait(0);
    }

    protected void finalize() throws Throwable { }
}

首先我们发现Object中几乎所有的方法声明都有一个native关键字,这个关键字有什么用呢?它的作用就是告诉JVM,我的实现方法不在这里,我需要操作系统层面的帮助,我被调用的时候操作系统你得给我对应的实现。说白了,它的实现在.dll中或者在.so中(不同平台)。

接下来我们看看各个方法的作用吧。

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

上面的registerNatives主要作用就是将C/C++中的方法映射到Java中的native方法,实现方法命名的解耦,下面的static方法块的作用就是这个类在被类加载器加载时执行一次,且仅执行一次。关于static块的详解可以参考这里:http://www.cnblogs.com/shaweng/p/3921537.html

    public final native Class<?> getClass();

在学习反射的时候是不是经常用到这个函数?getClass方法的主要作用是在运行时获取类类型,即返回一个java.lang.Class的实例,获取这个实例之后就能使用这个类的方法了。

    public native int hashCode();

这个方法老司机应该用得比较多了,获取的是类实例在JVM中的哈希码,唯一的。

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

注意了,原生的equals是比较两个对应的内存地址是一样。如果要比较两个实例的内容则需要重写这个方法,这也是开发过程中经常遇到的,老司机默默的笑了。

    public final native void notify();
    public final native void notifyAll();

上面这两个方法都是关于并发这块的。notify的主要作用就是通知一个其他想要获取这个对象控制权的线程,notify则是通知全部其他想要获取这个对象控制权的线程,比如A/B/C三个线程,A/B/C都在等待获取Q对象的控制权,Q被某个线程执行,当这个线程执行完之后,会释放这个控制权,假设这时调用了Q对象的notify方法,则ABC当中有一个会被唤醒获得D对象的控制权;如果调用的是Q对象的notifyAll方法,则ABC都会被唤醒,这个时候就会产生竞争,哪个线程会获得控制权就得看实际的竞争条件了。PS,一般情况下,推荐使用notifyAll。

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

    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 void wait() throws InterruptedException {
        wait(0);
    }

wait这个方法主要的作用就是放弃目前对象的控制权,让给其他等待这个对象控制权的线程。大家看一下wait(long timeout, int nanos)的实现,如果nano大于0则timeout加一毫秒。关于wait我稍微延伸一下,很多时候面试会被问wait和sleep的区别。这个只要理解它们的本质就好:wait是让出对象的控制权,让其他线程可以控制这个对象,sleep则是让出cpu,让其他等待cpu的线程执行,完全不一样的的东西。

    protected void finalize() throws Throwable { }

finalize是Java GC这块的方法,对象如果确定要被垃圾回收,则这个方法会被调用,它标记这个对象是待回收对象,但是它不会马上被回收,需要等待下一次GC才会被回收。这就是老司机经常说的:即使你调用finalize方法这个对象也不会马上回收。

浅浅的探索了一下所有Java类对象的祖先Object,希望可以加深各位在开发过程中对类的印象。

PS:我把Java经常使用的部分源码放上了我的Oscgit:https://gitee.com/gongwilliam/jdksrc,有需要的朋友可以去拿来看看或者研究一下,顺便帮我star一下,谢谢。

Object类文件位于lang包下面。

参考:

http://www.2cto.com/kf/201609/546746.html

© 著作权归作者所有

gongwilliam
粉丝 2
博文 14
码字总数 12127
作品 0
深圳
私信 提问
加载中

评论(0)

从1+1=2来理解Java字节码

背景 前不久《深入理解Java虚拟机》第三版发布了,赶紧买来看了看新版的内容,这本书更新了很多新版本虚拟机的内容,还对以前的部分内容进行了重构,还是值得去看的。本着复习和巩固的态度,...

木木匠
2019/12/30
6K
11
Groovy核心类源码讲解(终)

前两篇groovy我们从源码的角度分析了,groovy对java做了那些扩展和这些扩展的实现的原理,今天这篇文章,我们来讲解groovy源码分析中的最后一部分,来分析一下groovy中最后一部分对java做了那...

qndroid
2018/07/19
0
0
《成神之路-基础篇》Java基础知识——常用的Java工具库

本文是《成神之路系列文章》的第一篇,主要是关于JVM的一些介绍。 持续更新中 commons.lang https://commons.apache.org/proper/commons-lang/ commons.*… guava-libraries Google guava工具...

HollisChuang's Blog
2018/10/14
0
0
【目录导航】JAVA零基础进阶之路

【JAVA零基础入门系列】(已完结)导航目录 Day1 开发环境搭建 Day2 Java集成开发环境IDEA Day3 Java基本数据类型 Day4 变量与常量 Day5 Java中的运算符 Day6 Java字符串 Day7 Java输入与输出...

MFrank
2018/06/21
0
0
在Android Studio中编译谷歌自带输入法

介绍 近期开始做输入法的项目,所以必须要解决一些工程问题,在此记录下 第一篇先介绍编译篇,后续会增加java代码和native的代码分析篇 开始动手 首先,从谷歌的AOSP(Android Open Source Pr...

小包July
2016/12/03
0
0

没有更多内容

加载失败,请刷新页面

加载更多

第二天

独立工程就是打成一个war包,war包可以部署到不同的服务器中; 聚合工程至少有一个是war包,去除web后manager聚合工程剩余dao、service、pojo、interface,把service改成war包 main下加入web...

七宝1
37分钟前
19
0
开源:从“复兴”走向“商业化”

在美国版“知乎”Quora上搜“Open Source(开源)”,出来第一条问题是: “Linux的失败真的是因为开源吗?”。其中一个回答给我很多启发: “有些人把安卓和Chrome OS的成功归结于Linux开源...

编辑部的故事
今天
299
0
JavaScript等同于printf / String.Format - JavaScript equivalent to printf/String.Format

问题: I'm looking for a good JavaScript equivalent of the C/PHP printf() or for C#/Java programmers, String.Format() ( IFormatProvider for .NET). 我正在寻找一个等效于C / PHP p......

javail
今天
27
0
什么是Android上的“上下文”? - What is 'Context' on Android?

问题: In Android programming, what exactly is a Context class and what is it used for? 在Android编程中, Context类到底是什么?它的用途是什么? I read about it on the developer......

技术盛宴
今天
26
0
OkHttp配置HTTPS访问+服务器部署

1 概述 OkHttp配置HTTPS访问,核心为以下三个部分: sslSocketFactory() HostnameVerifier X509TrustManager 第一个是ssl套接字工厂,第二个用来验证主机名,第三个是证书信任器管理类.通过OkHtt...

氷泠
今天
26
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部