什么是对象?
学习Java的朋友,想必都知道Object对象吧,哈哈哈,不知道也没关系,我们大家就来一起研究研究这个类。说起这个Object,还得从Java语言开始说起,Java是一款面对对象的编程语言,什么是面对对象呢?
最早的时候,编程语言其实是面对过程的,很好理解,因为我们编程其实就是为了解决实际计算过程中的问题,通过步骤1,2,3 这个的方式解决问题。但是当相同的过程多了以后,代码的重复率就高了,而且还不好统一维护。举个例子:
如果我们要发短信,我们可能会经过这几个步骤:
步骤1:写上收信人,写上寄件人
步骤2:写上信息内容
步骤3:发送
如果我要写过1000个人,按照面向过程的方式,我们可能就是,copy 1000次步骤1,2,3 的代码,然后把收信人和寄件人改下就好了。大家仔细想想,步骤2和3的代码内容是不是重复了1000次了,如果以后 写信的方式和发送的方式改变了,是不是对应的就得修改1000次代码了
俗话说,有矛盾的地方,有意思的思想也就悄悄萌发了
这个就是面对对象编程。面向对象程序设计语言中提供了类、继承等成分,有识认性、多态性、类别性和继承性四个主要特点。
怎么解决上面发送短信的问题呢?既然是面对对象,那我就设计一个短信对象,这个短信对象和我们理解中现实生活的信封一样,我们现实中信封都有,收信人,寄件人,内容,同时再赋予这个信封一个行为(方法函数)发送。
这样我们每次发送短信的时候,只是创建一个短信对象,传入收信人,寄件人,内容,执行发送的行为就可以了。
其实对象本质上也是一种抽象的数据结构
那Object和对象又有什么关系?
在Java中 Object 就是一个对象,只是比较特殊,Object 类是所有类的父类,也就是说 Java 的所有类都继承了 Object,子类可以使用 Object 的所有方法。(Object 就是 Java 中所有类的祖宗)可以理解成这个对象是所有具体对象的抽象,我们把世界万物都可以看成是一个 Object,植物是一个 Object,动物是一个Object,你也是一个Object。
Obejct 的结构
Object 中没有设置属性,但是却定义了,所有类的通用方法
protected Object clone()
创建并返回一个对象的拷贝
boolean equals(Object obj)
比较两个对象是否相等,(默认比较的是对象存储于堆内存的地址)
protected void finalize()
当 GC (垃圾回收器) 确定不存在对该对象的有更多引用时,由对象的垃圾回收器调用此方法。
(垃圾收集器第一次执行 GC 的时候会调用该方法,但是如果在执行该方法的时候,重新引用自身,
后续的 GC 操作将不在执行该方法)
Class<?> getClass()
获取对象的运行时对象的类
int hashCode()
获取对象的 hash 值, 默认情况下,该方法会根据对象的地址来计算,不同对象的 hashCode() 的值一般是不相同。但是,同一个对象的hashCode() 值肯定相同。
void notify()
唤醒在该对象上等待的某个线程
void notifyAll()
唤醒在该对象上等待的所有线程
String toString()
返回对象的字符串表示形式
void wait()
让当前线程进入等待状态。直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法。
void wait(long timeout)
让当前线程处于等待(阻塞)状态,直到其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过参数设置的timeout超时时间。
void wait(long timeout, int nanos)
与 wait(long timeout) 方法类似,多了一个 nanos 参数,这个参数表示额外时间(以纳秒为单位,范围是 0-999999)。 所以超时的时间还需要加上 nanos 纳秒。。
补充:
- 如何使用clone方法
1. 第一步在对象类中实现Cloneable接口
2. 第二步在对象类中重写clone方法
clone出来的对象不一样,但是其中的成员变量中对象是同一个 [所为的浅拷贝]
存在的危害:
因为里面的成员变量对象地址是一样的,如果修改其中的成员变量的属性值的话,
两个对象的值都会发生变化
建议:
如果需要使用拷贝方法,建议使用深拷贝
示例:
- finalize方法
判定死亡
"GC ROOTS"定义:GC管理的主要区域是Java堆,一般情况下只针对堆进行垃圾回收。
方法区、栈和本地方法区不被GC所管理,因而选择这些区域内的对象作为GC roots,被GC roots引用的对象不被GC回收。
"GC ROOTS"也可以看做是引用链的最顶级。
Java采用可达性分析算法来判定一个对象是否死期已到。Java中以一系列"GC Roots"对象作为起点,如果一个对象的引用链可以最终追溯到"GC Roots"对象,那就天下太平。
否则如果只是A对象引用B,B对象又引用A,A,B引用链均为能达到"GC Roots"的话,那它俩将会被虚拟机宣判符合死亡条件,具有被垃圾回收器回收的资格。
最后的救赎
上面提到了判断死亡的依据,但被判断死亡后,还有生还的机会。
如何自我救赎:
1.对象覆写了finalize()方法(这样在被判死后才会调用此方法,才有机会做最后的救赎);
2.在finalize()方法中重新引用到"GC Roots"链上(如把当前对象的引用this赋值给某对象的类变量/成员变量,重新建立可达的引用).
需要注意:
finalize()只会在对象内存回收前被调用一次(The finalize method is never invoked more than once by a Java virtual machine for any given object. );
finalize()的调用具有不确定行,只保证方法会调用,但不保证方法里的任务会被执行完(比如一个对象手脚不够利索,磨磨叽叽,还在自救的过程中,被杀死回收了)。