想要深入学习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的时候都学过的,都留给平时去应用吧。

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

JAVA源码之JDK(一)——java.lang.Object的更多相关文章

  1. JAVA源码之JDK(二)——Integer、Long、Double

    这篇文章继续java.lang包下的源码学习,笔者也是找了几个比较常用的来阅读.下面针对Integer.Long.Double这样的基本类型的封装类,记录一些比较经典.常用的方法的学习心得,如toSt ...

  2. JAVA源码之JDK(三)——String、StringBuffer、StrinBuilder

    Java中,除了8种基本类型,最长用的应该就是String类了.那么我们来看看JDK中的源码是怎么建造String.StringBuffer.StrinBuilder一系列类的. java.lang. ...

  3. Java源码系列2——HashMap

    HashMap 的源码很多也很复杂,本文只是摘取简单常用的部分代码进行分析.能力有限,欢迎指正. HASH 值的计算 前置知识--位运算 按位异或操作符^:1^1=0, 0^0=0, 1^0=0, 值 ...

  4. Java源码系列1——ArrayList

    本文简单介绍了 ArrayList,并对扩容,添加,删除操作的源代码做分析.能力有限,欢迎指正. ArrayList是什么? ArrayList 就是数组列表,主要用来装载数据.底层实现是数组 Obj ...

  5. Java 源码学习线路————_先JDK工具包集合_再core包,也就是String、StringBuffer等_Java IO类库

    http://www.iteye.com/topic/1113732 原则网址 Java源码初接触 如果你进行过一年左右的开发,喜欢用eclipse的debug功能.好了,你现在就有阅读源码的技术基础 ...

  6. 一点一点看JDK源码(二)java.util.List

    一点一点看JDK源码(二)java.util.List liuyuhang原创,未经允许进制转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 List译为表,一览表, ...

  7. 一点一点看JDK源码(三)java.util.ArrayList 前偏

    一点一点看JDK源码(三)java.util.ArrayList liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 ArrayLi ...

  8. 一点一点看JDK源码(四)java.util.ArrayList 中篇

    一点一点看JDK源码(四)java.util.ArrayList 中篇 liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 1.综述 在前篇中 ...

  9. 一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach

    一点一点看JDK源码(五)java.util.ArrayList 后篇之forEach liuyuhang原创,未经允许禁止转载 本文举例使用的是JDK8的API 目录:一点一点看JDK源码(〇) 代 ...

随机推荐

  1. GridView中实现全选与取消全选,以便同时删除多条数据

    我们项目后台操作中不可避免的会有同时删除多项的操作,本文实现的就是当点击全选时,选定当前页中所有项,当取消了某一项的选定,则“全选”CheckBox的checked也为false:然后在后台中取到所选 ...

  2. 使用 scikit-learn 实现多类别及多标签分类算法

    多标签分类格式 对于多标签分类问题而言,一个样本可能同时属于多个类别.如一个新闻属于多个话题.这种情况下,因变量yy需要使用一个矩阵表达出来. 而多类别分类指的是y的可能取值大于2,但是y所属类别是唯 ...

  3. cmd隐藏指定文件

    隐藏文件: 或者带路径执行: 显示文件:

  4. 自定义 XIB subview的时候 为什么控件都是 空的

    http://blog.wtlucky.com/blog/2014/08/10/nested-xib-views/

  5. 怎样优化UITableView的性能

    在iOS App中,UITableView应该是使用率最高的.同一时候也是最为复杂的视图. 差点儿全部自带的应用中都能看到它的身影,可见它的重要性. 在使用UITableView时,会常常遇到性能上的 ...

  6. 【Shader】人物选中高亮状态

    Shader "OutLine/RedOutLine" { Properties { _Switch("Value",Range(0,1)) = 0 _Main ...

  7. firefox配置

    Firefox23取消了一个很人性化的功能,就是在GUI界面中禁用JavaScript,对于这点我很不能理解!JavaScript是所有网页木马 的源头,防人之心不可无,FireFox就这么确信能防住 ...

  8. vi/vim 光标移动命令

    vi/vim 光标移动命令 移动光标上:k nk:向上移动n行 9999k或gg可以移到第一行 G移到最后一行下:j nj:向下移动n行左:h nh:向左移动n列右:l nl:向右移动n列 w:光标以 ...

  9. MapReduce实战(五)实现关联查询

    需求: 利用MapReduce程序,实现SQL语句中的join关联查询. 订单数据表order: id date pid amount 1001 20150710 P0001 2 1002 20150 ...

  10. 成功抓取csdn阅读量过万博文

    http://images.cnblogs.com/cnblogs_com/elesos/1120632/o_111.png var commentscount = 1; 嵌套的评论算一条,这个可能有 ...