Java(五) Object

2 篇文章 0 订阅

什么是Object

    Object在有道翻译的意思是目标,物体
    在Java中Object 是java.lang包下面的类,该类是类层次结构的根类,每个类都使用Object作为超类了。所有对象(包括数组)都实现这个类的方法。 
JDK1.0开始使用

属性

//registerNatives采用JNI调用C函数,注册到jvm 虚拟机中
private static native void registerNatives();
    static {
        registerNatives();
    }
static JNINativeMethod methods[] = {
    {“hashCode”, “()I”, (void *)&JVM_IHashCode},
    {“wait”, “(J)V”, (void *)&JVM_MonitorWait},
    {“notify”, “()V”, (void *)&JVM_MonitorNotify},
    {“notifyAll”, “()V”, (void *)&JVM_MonitorNotifyAll},
    {“clone”, “()Ljava/lang/Object;”, (void *)&JVM_Clone},
};
//C的registerNatives函数
JNIEXPORT void JNICALL
Java_java_lang_Object_registerNatives(JNIEnv *env, jclass cls){
    (*env)->RegisterNatives(env, cls,methods, sizeof(methods)/sizeof(methods[0]));
}

构造方法

Object() 默认构造方法

方法

getClass

源码
    public final native Class<?> getClass();
API
    public final Class<?> getClass() 
        返回:
            表示此对象运行时类的 Class 对象。由所表示类的 static synchronized 方法锁定的对象。 

hashCode

源码
    public native int hashCode();
API
    public int hashCode()

    返回:
    此对象的一个哈希码值。

equals

源码
    public boolean equals(Object obj) {
        return (this == obj);
    }
API
    public boolean equals(Object obj)
        自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。 
        对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。 
        传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。 
        一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。 
        对于任何非空引用值 x,x.equals(null) 都应返回 false。 
        Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。 

    参数:
        obj - 要与之比较的引用对象。 
    返回:
        如果此对象与 obj 参数相同,则返回 true;否则返回 false。

clone

源码
    protected native Object clone() throws CloneNotSupportedException;
API
    protected Object clone()
            throws CloneNotSupportedException
对于x进行浅克隆: (一个类及其所有的超类(Object 除外)都遵守此约定)
        x.clone() != x为 true,
        x.clone().getClass() == x.getClass()也为 true,
        x.clone().equals(x)为 true

    注意:
        Object 类的 clone 方法执行特定的复制操作。如果此对象的类不能实现接口 Cloneable,则会抛出 CloneNotSupportedException。所有的数组都被视为实现接口 Cloneable。
        Object 类本身不实现接口 Cloneable,所以在类为 Object 的对象上调用 clone 方法将会导致在运行时抛出异常。 
    返回:
        此实例的一个副本。 
    抛出: 
        CloneNotSupportedException 

toString

源码
     public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
API
public String toString()
    返回该对象的字符串表示。建议所有子类都重写此方法。
    类名+ @ + 转成16进制的哈希值(内存值)
    getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
    该对象的字符串表示形式。例如:java.lang.Object@6fd2300e

notify

源码
     public final native void notify();
API
    唤醒此对象监视器上面的单个线程,如果有多个线程,则是任意一条线程被唤醒,如果两条线程同时执行的话,线程会调用wait方法,让一个线程等待。
    成为所有者 有三种方法
        1.通过此对象的同步实例方法。
public synchronized void n() {
    notify();
}
        2.通过执行在此对象上进行同步的 synchronized 语句的正文。 
public void n() {
    //同步本class
    synchronized (this) {
        notify();
    }
}
        3.对于 Class 类型的对象,可以通过执行该类的同步静态方法。 
public class SynchronizedStatic implements Runnable {

    private static boolean flag = true;
    // 类对象同步方法一:
    // 注意static修饰的同步方法,监视器:SynchronizedStatic.class
    private static synchronized void testSyncMethod() {
        for (int i = 0; i < 100; i++) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    // 类对象同步方法二:
    private void testSyncBlock() {
        // 显示使用获取class做为监视器.它与static synchronized method隐式获取class监视器一样.
        synchronized (SynchronizedStatic.class) {
            for (int i = 0; i < 100; i++) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    public void run() {
        // flag是static的变量.所以,不同的线程会执行不同的方法,只有这样才能看到不同的锁定效果.
        if (flag) {
            flag = false;
            testSyncMethod();
        } else {
            flag = true;
            testSyncBlock();
        }
    }

    public static void main(String[] args) {
        ExecutorService exec = Executors.newFixedThreadPool(2);//调用线程池
        SynchronizedStatic rt = new SynchronizedStatic();
        SynchronizedStatic rt1 = new SynchronizedStatic();
        exec.execute(rt);//执行
        exec.execute(rt1);
        exec.shutdown();//关闭线程池
    }
}
    抛出: 
        IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。

notifyAll

源码
 public final native void notifyAll();
API
    public final void notifyAll()
        唤醒在此对象监视器上等待的所有线程。
    抛出: 
        IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。

wait

源码
  public final native void wait(long timeout) throws InterruptedException;
API
    public final void wait(long timeout)throws InterruptedException
    在其他线程调用此对象的 notify() 方法或 notifyAll() 方法,或者超过指定的时间量前,导致当前线程等待。 
    此方法导致当前线程(称之为 T)将其自身放置在对象的等待集中,然后放弃此对象上的所有同步要求。出于线程调度目的,在发生以下四种情况之一前,线程 T 被禁用,且处于休眠状态: 
        其他某个线程调用此对象的 notify 方法,并且线程 T 碰巧被任选为被唤醒的线程。 
        其他某个线程调用此对象的 notifyAll 方法。 
        其他某个线程中断线程 T。 
        大约已经到达指定的实际时间。但是,如果 timeout 为零,则不考虑实际时间,在获得通知前该线程将一直等待。 
    synchronized (obj) { 
        while (<condition does not hold>) 
            obj.wait(); 
        ... // Perform action appropriate to condition 
    } 
    线程虚假唤醒解决:
        1.  使用可同步的数据结构来存放数据,比如LinkedBlockingQueue之类。由这些同步的数据结构来完成繁琐的同步操作。
        2.  双层的synchronized使用没有意义,保留外层即可。
        3.  将if替换为while,解决虚假唤醒的问题。
    参数:
        timeout - 要等待的最长时间(以毫秒为单位)。 
    抛出: 
        IllegalArgumentException - 如果超时值为负。 
        IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 
        InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

线程虚假唤醒例子

wait

源码
  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);
    }
API
    public final void wait(long timeout,int nanos)throws InterruptedException
    此方法类似于一个参数的 wait 方法,但它允许更好地控制在放弃之前等待通知的时间量。用毫微秒度量的实际时间量可以通过以下公式计算出来: 
    1000000*timeout+nanos
需要特别指出的是,wait(0, 0) 与 wait(0) 相同。 
当前线程必须拥有此对象监视器。该线程发布对此监视器的所有权,并等待下面两个条件之一发生: 
    其他线程通过调用 notify 方法,或 notifyAll 方法通知在此对象的监视器上等待的线程醒来。 
    timeout 毫秒值与 nanos 毫微秒参数值之和指定的超时时间已用完。 
    参数:
        timeout - 要等待的最长时间(以毫秒为单位)。
        nanos - 额外时间(以毫微秒为单位,范围是 0-999999)。 
    抛出: 
        IllegalArgumentException - 如果超时值是负数,或者毫微秒值不在 0-999999 范围内。 
        IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 
        InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

wait

源码
   public final void wait() throws InterruptedException {
        wait(0);
    }
API
    public final void wait()throws InterruptedException
        一直等待
    抛出: 
        IllegalMonitorStateException - 如果当前线程不是此对象监视器的所有者。 
        InterruptedException - 如果在当前线程等待通知之前或者正在等待通知时,任何线程中断了当前线程。在抛出此异常时,当前线程的中断状态 被清除。

finalize

源码
    protected void finalize() throws Throwable { }
API
    protected void finalize() throws Throwable
    当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。子类重写 finalize 方法,以配置系统资源或执行其他清除。 
    finalize 的常规协定是:当 JavaTM 虚拟机已确定尚未终止的任何线程无法再通过任何方法访问此对象时,将调用此方法,除非由于准备终止的其他某个对象或类的终结操作执行了某个操作。finalize 方法可以采取任何操作,其中包括再次使此对象对其他线程可用;不过,finalize 的主要目的是在不可撤消地丢弃对象之前执行清除操作。例如,表示输入/输出连接的对象的 finalize 方法可执行显式 I/O 事务,以便在永久丢弃对象之前中断连接。 

    Object 类的 finalize 方法执行非特殊性操作;它仅执行一些常规返回。Object 的子类可以重写此定义。 
    Java 编程语言不保证哪个线程将调用某个给定对象的 finalize 方法。但可以保证在调用 finalize 时,调用 finalize 的线程将不会持有任何用户可见的同步锁定。如果 finalize 方法抛出未捕获的异常,那么该异常将被忽略,并且该对象的终结操作将终止。 
    在启用某个对象的 finalize 方法后,将不会执行进一步操作,直到 Java 虚拟机再次确定尚未终止的任何线程无法再通过任何方法访问此对象,其中包括由准备终止的其他对象或类执行的可能操作,在执行该操作时,对象可能被丢弃。 
    对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。 
    finalize 方法抛出的任何异常都会导致此对象的终结操作停止,但可以通过其他方法忽略它。 
    抛出: 
        Throwable - 此方法抛出的 Exception

现在没有基础可能看不懂,可以看看后面用到的技术,如线程,类的加载机制,JNI

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值