入行许久,对于java一些基础知识开始做点总结。首先从我们最开始入门的object类开始。
这个类是java体系的最元老级别的类,也一定程度上承载着java这门从编程语言的精髓思想。
Object类
组成如下:
由图可知,object类除去object()之外,有11个成员方法。object()是构造方法。
下面来回顾下object类的方法的作用。
注:由于某些方法的作用是相辅相成,关系密切的,所以可能会放在一起讲解。
1、clone()方法
这个方法是为object的克隆对象的而生。有些人可能会不明白,克隆不就是copy吗?copy不就是跟new一个对象差不多嘛?
其实不然,clone()方法存在的意义在于java语言的对象引用机制。
如:
Person p1 = new Person();
Person p2 = p1;
此时,p1和p2是引用的同一个对象的,这个对象是在jvm的堆内存中共享的。也就睡说。如果p2被一系列操作改变了它本身的属性值,那么p1也会跟着改变,至始至终,p1和p2引用的是同一个东西。
那么要避免p1跟着p2发生变动,应该怎么做呢?
那就是可以使用到clone()方法了。使用这个方法可以在堆中克隆出另一个对象,这样一来,p2变动,p1就不会变了,因为他们引用的不再是同给一个对象。
clone方法的使用上,要注意,首先要实现Cloneable的接口,然后在类中重写Object类中的clone方法,具体过程可以自行研究,不做赘述。
2、equal()和hashCode()方法
这两个方法是面试经典。也是比较重点要掌握的方法。毕竟做java的,对equal()不可能不熟悉。
在Java中,有时候要判断两个对象之间的想的相等关系,并不是想象中那么容易的。因为我们无法通过代数中的"="或者"=="来粗暴的断定。
"=="只是比较两个对象的地址是否一致,当然,如果返回true,那说明这两个对象确实是相等的。因为每个对象在内存中都是有着不同的
存放地址,地址相同自然就是同一个对象了。但大部分时候,我们所谓的比较两个对象是否相等时,并不是将引用同一个对象的引用来比
较的。就比如,随便new 两个对象进行比较,这就要注意了,因为两个都是新生成的对象,内存地址肯定是不一样的,这个时候再用"=="比
较,肯定个不可能返回true(前提是没有重写hashcode()和equal()),有人会说了,既然不返回true,那是不是就说明这两个对象不相等?
事实上,并非如此。比如,你身上有一百块钱,我身上也有一百块钱,显然这两张一百块钱不是同一回事儿。但是不是相等的呢?
显然是的。
因为我们所谓的相等,是从价值上来比较的,同样是一百块钱 ,能买的东西是一样的多,自然是相等的。
可见,程序里面的对象是否相等,并不是但从地址是否一致来考量的,还要从程序员的比较和考量的的角度(比较,比较两百块钱是比较价值,
而并非比较新旧程度)来定的。
那么说了这么多,终于要进入正题了。
hashcode()方法其实就是对应对象的地址,调用它的时候,它的返回值就是对象的地址。
equal()方法则是比较两个对象的具体方法描述,或者说规则。也就是说,你要比较两个对象是否相等。你的比较原则是什么,怎么去比较,
就重写在equal()方法中。
此方法在默认情况下也是"==",有兴趣的童鞋可以去看源码,非常简单。
由于这两个方法是面试的重点,我希望大家都可以很好的理解。大家可以好好去研究下hashset()实现比较的原理来帮助理解,这个网上有很
多资料,大家可以自行去研究。
还有一点,大家需要注意的是,一般情况下,如果要比较两个对象是否相等,直接用equal()就可以了,之所以还要有hashcode(),是出于效率来
考虑,毕竟如果hashcode()方法返回为false的话,也就不会需简要去比较equal()了。
3、finalize()
这个方法是专供垃圾回收提供的,垃圾回收期跳如果要针对一个类的对象进行回收,那么它会先调用finalize()方法,但要注意,并非调用了
finalize(),就马上会
回收。java的垃圾回收机制是无法认为预测的,它只在jvm认为合适的时候才会进行回收。而所谓的合适,唯一的判断标准就是内存不足。
4、getClass()
此方法与反射有关。用于返回一个返回该对象的运行时类的java.lang.Class对象。也就是运行中的对象本身。
5、notify、notifiAll和wait()
对多线程熟悉的童鞋应该比较清楚这三个方法。这三个方法是相辅相成来实现多线程的。
wait()来阻塞线程,wait()被调用后,线程将会进行等待状态,锁被释放,同时线程也会让出cpu资源,其他的线程可以运行。
notify\notifyAll方法用于唤醒线程,调用notify\notifyAll方法后,不会立即释放锁,而是等待sychronize代码块执行完后。或者遇到
wait()方法后,在释放锁。因此,有一点要非常注意,notify、notifiAll和wait()是必须在sychronize包含的代码快中使用。这跟thread
类的sleep方法是不一致的,sleep()方法可以在任意地
方使用。
6、toString()
toString()方法就更不用多说了,很多时候我们会在类里面重写这个方法。它默认的作用是就对象转化为字符串的形式。如果是基础数据类型,
如int ,long,byte等等,但如是引用对象,toString()将会转化为该对象的内存地址。
(本篇完)