想要深入学习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. Handler源代码解析-有关Handler那些事

    Handler被成为异步处理大师.相信大家都会用,面试中也常常会问到Handler的底层原理.今天就来看一看Handler的机制. Android的消息处理有四个核心类:Handler.Looper. ...

  2. Python zip Python zip函数

    zip([iterable, ...])zip()是Python的一个内建函数,它接受一系列可迭代的对象作为参数,将对象中对应的元素打包成一个个tuple(元组),然后返回由这些tuples组成的li ...

  3. printf函数对参数的计算顺序

    没想到啊,没想到: printf函数对参数的计算顺序是从右往左的! 我不禁想问一句,这么坑爹的事情,书里居然没有写过.还是我看书不仔细,没有找到?(回头,在自己翻翻那本c语言编程) 于是下面的程序结果 ...

  4. python-sqlite3之占位符

    The sqlite3 module supports two kinds of placeholders: question marks (qmark style) and named placeh ...

  5. 李洪强和你一起学习前端之(8)CSS复习

    今天是2017年3月24日周五 每一天都是余生当中最好的一天,珍惜当下. CSS基础复习 1 复习 1.1Css第一天 css层叠样式表 基础选择器 标签选择器 p{属性: 值;} 类选择器 .自定义 ...

  6. post请求与get请求

    $.post('/manage.aa', function (response) { agentList = response.data; }, 'json'); var categoryId; $. ...

  7. JQuery File Upload 插件 出现 “empty file upload result” 错误的解决方案。

    本例中采用的是 JQuery File Upload + ASP.NET 的方式, Google了大半天基本没有找到合理的解决方案,倒是在 NodeJS的一遍博客中找到了灵感:http://www.i ...

  8. 使用command对象添加删除查询记录

    private void button1_Click(object sender, EventArgs e) { //实例化数据库连接对象 SqlConnection sqlcon = new Sql ...

  9. TypeScript Visitor设计模式

    以下翻译脑袋的VBF项目,试试看TypeScript能否重写. class RegExpr {     Accept<T>(convert: Converter<T>) {   ...

  10. C++ 4种强制类型转换

    C++的四种强制类型转换为:static_cast.const_cast.reinterpret_cast和dynamic_cast 类型转换的一般形式:cast-name(expression); ...