前面我们基本学习完成了java的基本语法,这节课开始我们学习java 的一些常用对象。
这些对象由java基础库提供,我们会经常用到。必须要了解和学习。
本节课的内容:
1、Object类
2、Object类的方法
第一部分:Object
Object类是java.lang包下提供的类,不需要用户定义,就可以直接使用。
Object类是所有java类的root class(基类)。
java所有的类默认继承Object类。
为什么java要提供这么一个基类呢?
有很多很多的原因。比如说,java是面向对象的编程语言,也就是说每个类都是一组对象的抽象。那么,java如何用类表示所有的对象呢?
这就需要对所有的对象进行抽象,总结得到一个Object类,用来代表对象。
另外,我们后面学习的集合数组想存储不同类型的对象,就可以声明集合或数组为Object,达到类型的兼容。
再比如,我们之前学习知道java对象都有默认的构造器,就是因为默认继承了Object。
还有,对象的上转型或者父类方法的调用等等。都需要一个基类来解决这些问题,就产生了Object。
我们定义一个类,可以显式的继承Object。也可以不写继承声明,隐式的自动的继承Object。
换句话说,所有类对象都有Object的方法。
第二部分:Object的方法
为什么只讲方法呢?因为一旦存在属性,就变相的给对象打上了标签,所以,Object只抽象了所有对象的行为。
Object类中定义了12个方法,这12个方法是所有对象的抽象行为。我们来一一看下。
1、private static native void registerNatives();
这个方法是Object私有的方法,属于Native方法。什么是Native方法?就是非java的本地其他语言编写函数库方法,通过java与库交互的接口去调用。
那么,native就表示调用这类的方法。那这个registerNatives做什么呢?就是将本地的方法注册进来,当对象用到的时候可以调用。
2、public final native Class> getClass()
这个方法返回对象运行时的类对象,也就是对象class的结构,当中包含对象的属性和方法,甚至注解、接口等等信息。这个方法也是java反射(后续会讲)的基础。
3、public native int hashCode();
这个方法返回对象的哈希值。哈希值是通过哈希算法,将任意长度的数值映射为固定长度二进制,这个映射后的二进制值就是哈希值。
如果源数据发生变化,哪怕一个字符,计算后的哈希值也不同,所以用来加密或者签名,java当中也用来地址定位。
后面接触到的hashtable或hashmap就是通过hashcode计算key的位置 的。
4、 public boolean equals(Object obj) {
return (this == obj);
}
这个方法用于判断两个对象是否相等。
在Object类里,判断对象相等使用==。这个表示两个对象的引用地址相同。也就是说,两个对象实际引用了同一个对象(的内存地址)。
如果自己需要重新定义两个对象相等的规则,则需要自己重写equals方法。
但是,如果重写equals方法,建议必须重写hashcode方法,因为他们会同时对hash表存储造成影响。(具体查阅hashmap实现)。
5、 protected native Object clone() throws CloneNotSupportedException;
clone方法。用于拷贝对象,产生一个对象的拷贝。要使用这个方法的类,必须实现java.lang.Cloneable接口,实现对象的克隆逻辑,
,否则会抛出CloneNotSupportedException异常。
Cloneable接口中不包含任何方法,所以实现它时只要在类声明中加上implements语句即可。
第二个比较特殊的地方在于这个方法是protected修饰的,覆写clone()方法的时候需要写成public,才能让类外部的代码调用。
6、 public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
这个方法返回对象的字符串表达。在Object里默认为类名+@+对象的hash字符串。
如果你想让toString返回你想要的字符串结果,显示对象的属性或内容,就必须重写该方法。
7、 public final native void notify();
这个方法用于唤醒线程队列中一个等待线程。具体唤醒那个线程由jvm调度。并且该方法的使用必须满足两个条件:
1、持有对象的实例
2、持有对象的锁,一般为同步代码块。
8、 public final native void notifyAll();
此方法用于唤醒线程队列中的所有等待线程。具体运行那个线程需要这些唤醒的线程去竞争对象的锁。
9、 public final native void wait(long timeout) throws InterruptedException;
此方法用于让一个线程进入等待状态,直到有对象唤醒他。或者让一个线程等待一段时间。
10、 public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos >= 500000 || (nanos != 0 && timeout == 0)) {
timeout++;
}
wait(timeout);
}
此方法是类似于一个参数的wait方法,但它可以更精确地控制大量的时间等待通知之前放弃。以纳秒为单位测量,实际时间量,由下式给出:
1000000*timeout+nanos
11、 public final void wait() throws InterruptedException {
wait(0);
}
此方法用于让一个线程进入等待状态,直到有对象唤醒他。
12、protected void finalize() throws Throwable { }
调用垃圾回收期进行对象的回收(取决于是否有使用引用)。该方法由jvm调用,编程人员不建议使用。