现在是2020年9月15日08:49:42,开始在Java基础之上的Java API介绍,本次的主角是万类之祖——Object。
1、API
API(Application Programming Interface,应用程序接口)是系统预先编写好的方法接口,开发者只需要调用他们进行开发即可,无须了解底层的实现原理,相当于C语言include的.h文件。这也是一种面向接口编程思想的体现。
任何编程语言都有自己的一套丰富的API,随着技术的更新迭代不断扩展升级,引入各种各样的新机制、新工具,这将会为开发者带来开发时的极大便利,无须自己完全从零开始,能够站在更高一级的层次进行开发。
作为初学者,Java语法知识掌握了大概之后,首先需要了解Java 的API。所谓“工欲善其事必先利其器”,了解并掌握Java的常用API,懂得底层的实现原理,才能进一步巩固基础,为更高级的框架的学习带来事半功倍的效果。
既然需要了解Java API的使用和底层实现原理,那么必须要有两个东西。因为需要使用API,所以我们需要查阅API帮助文档;因为需要理解API的底层原理,我们需要拿到API的源码。注意:帮助文档与源码对应的版本必须是相同的,本博客中采用的是JDK8版本的帮助文档和源码。
2、Object
(1)介绍
(1)Object类是所有类的祖先——任何类都是直接或者间接继承了Object类,如果代码中没有明确继承哪个父类,那么默认继承Object类。
(2)根据实际开发的业务需求,需要对自己定义的类重写他们的根类Object中的某个方法,比如:toString()、equals()、hashCode()方法等。
(2)方法
- 方法源码及其介绍(介绍藏在源码的注释里)
public class Object{
// String toString():返回对象的字符串表示形式
// Integer.toHexString(int):将int类型的数据转换成16进制的字符串
// Integer.toBinaryString(int):将int类型的数据转换成2进制的字符串
public String toString() {
// 将该对象的完整类名 与 @ 与 该对象的哈希码值对应的16进制字符串三者拼接在一起,组合成该对象的字符串表示形式,这个方法以后自定义时经常需要重写
// 在System.out.println(arg);传入参数arg的过程中,如果涉及到引用的打印输出,则会调用该对象的toString方法完成打印
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
//int hashCode():返回对象的哈希码值
public native int hashCode();// 本地方法
//boolean equals(Object obj):比较不同引用指向的对象内存地址是否相同
// 当业务需要时,需要重写该方法
public boolean equals(Object obj) {
return (this == obj);
}
//protected Object clone():创建并返回此对象的副本。
// 受保护的方法,使用它的对象必须实现java.lang.Cloneable接口,否则调用该方法会抛出异常
// 最好在实现Cloneable接口后实现自己的clone方法
// GoF23种设计模式之一的原型模式,拷贝对象(prototype)
protected native Object clone() throws CloneNotSupportedException;// 本地方法
//Class<?> getClass():获取引用指向对象的对应的Class
public final native Class<?> getClass();
//protected void finalize():当垃圾回收器要回收该对象时,调用该方法
protected void finalize() throws Throwable {}
// 以下三个方法在消费者和生产者模式使用,传说中的操作系统中的PV操作
//void notify():唤醒正在等待对象监视器的单个线程。
public final native void notify();
//void notifyAll():唤醒正在等待对象监视器的所有线程。
public final native void notifyAll();
// void wait():让在当前对象活动的当前线程处于等待状态,并释放该对象的锁。
// 直到另一个线程调用该对象的 notify()方法或 notifyAll()方法。
public final void wait() throws InterruptedException {
wait(0);
}
// void wait(long timeout):导致当前线程等待,直到另一个线程调用 notify()方法或该对象的notifyAll()方法,
// 或者指定的时间已过。
public final native void wait(long timeout) throws InterruptedException;
}
- 测试代码
package cn.drgn.javase.api;
public class ObjectTest{
public static void main(String args){
ObjectTest ot = new ObjectTest();
// 测试toString方法(该类重写了toString方法)
System.out.println(ot);// hello object
System.out.println(ot.toString);// hello object
// 测试equals()方法
ObjectTest ot2 = new ObjectTest();
System.out.println(ot == ot2);// false
System.out.println(ot.equals(ot2));// false
// 测试getClass方法
// 以下打印结果:cn.drgn.javase.api.ObjectTest
// 包名 + 简单类名 = 完整类名
System.out.println(ot.getClass().getName());
// 测试finalize()方法(该类重写了finalize方法,在垃圾回收之前被调用)
// 将ot置为null,则垃圾回收器将对空引用进行回收
ot = null;
// 该方法是通知垃圾回收器可以清除这里的垃圾了,记住:只是通知,它不一定马上就来
System.gc();
// 这里还有clone方法和wait/notify方法没有测试,
// 他们分别可以应用于原型模式、生产者与消费者模式,这里先按下不表,以后再详细讲解。
}
// 重写Object类的finalize方法,可以知道该对象垃圾何时被回收
@Override
protected void finalize() throws Throwable {
System.out.println("垃圾回收中.......");
}
// 重写了toString方法
@Override
public String toString() {
return "hello object";
}
}
(3)补充
(1)在上面源码中出现了native关键字,它修饰的是方法,表明该方法是本地方法,而非我们在类中用Java语言实现的Java方法。本地方法是由其他语言(如C、C++ 或其他汇编语言)编写,编译成和处理器相关的代码。
(2)在上面也提到了垃圾回收器,这涉及到了Java虚拟机(JVM)对内存资源进行管理的垃圾回收机制,由于本人最近还在学习JVM,还未完全吃透其中的原理,所以先按下不表,以后将再做更加详细地讲解。
(3)在上面还提到了设计模式,这里简要介绍一下,未来也会着重分享,毕竟说一个Java开发者不懂设计模式,那可能是天大的笑话。当然,设计模式不仅限于Java开发者,只要是面向对象的语言,就可以使用设计模式。
设计模式大概是这样子的:设计模式(design pattern)是对面向对象设计中反复出现的问题的解决方案,它是在对类、抽象类、接口之间关系之间的探索,在多个不同的使用场景下总结出来的设计方案,从而提高了代码的高质量,实现开发效果的提升。
设计模式不同于算法,设计模式是在面向对象的设计层面上优化方案,而算法是在面向过程的方法逻辑上优化方案,设计模式站在更高的层次上解决问题,但他们都是优化程序的两大角度。
Java界说的设计模式常常指的是GoF开发的23种设计模式,以后将重点介绍这23种设计模式。
好的,本次分享先到这里,如有错误,请多多指正,谢谢。