zoukankan      html  css  js  c++  java
  • JAVA源码之JDK(一)——java.lang.Object

      想要深入学习JAVA,还需追本溯源,从源码学起。这是我目前的想法。如今JAVA各种开源框架涌出,很多JAVA程序员都只停留在如何熟练使用的层次。身为其中一员的我深感惭愧,所以要加快学习的脚步,开始研究源码。希望这个系列我可以坚持下去。

      JAVA程序员都知道Object是所有类的父类,所以,今天就从Object开始记录我的源码之路。


    网上有很多关于Object类的详解,这里我只总结一点我所学到的,算是做个记录吧。

    首先要看Object.class中的几个方法:

    private static native void registerNatives();
    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 wait(long timeout) throws InterruptedException;
    protected void finalize() throws Throwable {}//空的方法

    话说在这之前我还不知道native关键字是什么意思。下面是我的总结:

    native

    • native用来修饰方法(Method),表示是另外一种语言实现的本地方法。看上去更像是一个调用非JAVA语言写的方法的接口。【JNI(Java native interface):JAVA本机接口
    • native方法可以和除了abstract的任何JAVA方法修饰符一起使用,如static、synchronized等。【例Object类中的registerNatives(),不能与abstract一起使用的原因可以猜得到:native有实现】
    • native方法的实现中可以访问JAVA特性,返回值也可以是一个JAVA类。【但是会很麻烦,FindClass()获取类、GetMethodId()获取方法、CallVoidMethod()调用方法等等,但一般这么调用效率较低,可尽可能用字节数组。
    • native方法可以被继承、可以抛异常等等。【与一个普通JAVA方法没什么两样。】

    native方法存在的意义【只是我粗浅的理解】

      JAVA语言是不能实现对操作系统底层的控制,这是为了让JAVA可以跨平台【不同的操作系统实现方式是不同的嘛】。这时候就要借助其它语言实现后,就可以通过JNI调用,就是这些native方法。其实这也就是JAVA跨平台的原理:使用其它语言【C\C++】针对不同操作系统写出不同的代码而实现同样的功能【如对内存、I/O的访问】,例如Object类中的notify()wait(long timeout),对于不同的操作系统调用不同的C语言的实现代码。

      网上找的native方法的用处:

    • 与旧有代码集成,避免重新编写。
    • 实现可用类库中所缺少的功能。举例来说,在 Java 语言中实现 ping 时,您可能需要 Internet Control Message Protocol (ICMP) 功能,但基本类库并未提供它。
    • 最好与使用 C/C++ 编写的代码集成,以充分发掘性能或其他与环境相关的系统特性。
    • 解决需要非 Java 代码的特殊情况。举例来说,核心类库的实现可能需要跨包调用或者需要绕过其他 Java 安全性检查。 

     native方法的简单实现

      基本有如下步骤,我自己没实现过,只是用于大致了解和记忆:

      1. 在JAVA中声明native Method;
      2. 用javah命令产生一个.h文件;
      3. 用C语言(C++)写.c文件(.cpp),其中要#include "CheckFile.h"和#include "jni.h"【虽然我没有看过jni.h,但猜测是声明或实现了FindClass()这种可以与JAVA交互的方法】;
      4. 将.c\.cpp文件生成.dll文件(动态链接库文件)。
      5. 在JAVA中用System.loadLibrary()方法加载.dll文件,这个native方法就可以在JAVA中被访问了。

      关于native就到此为止,这有一篇关于JNI的文章:http://www.ibm.com/developerworks/cn/java/j-jni/


      Object类中还有一些其它方法,如hashCode()和equals()这对组合。hash是一种程序员必须有的思想,具体会在后面HashMap的学习中详细记录,这里只写JDK的API上的解释:

    •  equals 方法体很简单,return (this == obj); 可以简单的理解为地址相同,下面是来自API的描述:

    equals 方法在非空对象引用上实现相等关系:

    • 自反性:对于任何非空引用值 xx.equals(x) 都应返回 true
    • 对称性:对于任何非空引用值 xy,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true
    • 传递性:对于任何非空引用值 xyz,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true
    • 一致性:对于任何非空引用值 xy,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
    • 对于任何非空引用值 xx.equals(null) 都应返回 false

    Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 xy,当且仅当 xy 引用同一个对象时,此方法才返回 truex == y 具有值 true)。

    注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。

    • hashCode 可以简单的认为返回的是对象的地址,但实际是经过一个算法处理成一个整数的。

    hashCode 的常规协定是:

    • 在 Java 应用程序执行期间,在对同一对象多次调用 hashCode 方法时,必须一致地返回相同的整数,前提是将对象进行 equals 比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
    • 如果根据 equals(Object) 方法,两个对象是相等的,那么对这两个对象中的每个对象调用 hashCode 方法都必须生成相同的整数结果。
    • 如果根据 equals(java.lang.Object) 方法,两个对象不相等,那么对这两个对象中的任一对象上调用 hashCode 方法 要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

      剩下的方法这里就不再赘述了,因为回到文章的主题是想学习源码,而java.lang.Object类实际并没有什么源码【都是native方法用其它语言实现的】,所以诸如clone()的浅拷贝、深拷贝,以及多线程相关等等一开始学JAVA的时候都学过的,都留给平时去应用吧。

      好了,关于源码的第一篇文章就到这里吧,还是开始提到的,希望我可以将这个系列坚持下去。

  • 相关阅读:
    OC ----关于时间的处理
    OC-- 判断字符串是否是纯数字
    OC 判断字符串是否只存在只有空格
    将Json字符串转换为数组
    调用接口时对参数的排序、生成签名、生成随机数,获取唯一标示符
    关于UIAlertView弹出警告框自动消失
    AVAudioPlayer 获取语音的长度(时间)
    AFN 请求 https get
    TableView  — reloadData     刷新
    mapView 地图视图
  • 原文地址:https://www.cnblogs.com/hanmou/p/3444144.html
Copyright © 2011-2022 走看看