• 浅谈Object


     《一》前言

    我们都知道Object是所有类的父类,任何类都默认继承Object类。

    《二》方法解析:

    1.hashCode():用来返回其所在对象的物理地址,也就是哈希码值,该方法用于哈希查找。

    2.equal():用来判断对象的值是否相等,若是值相同但是在不同的内存地址,返回的是false.

    如果希望不同内存但相同内容的两个对象equals时返回true,则我们需要重写父类的equal方法

    举几个例子方便理解:

    public class Main5 {
    
    	public static void main(String[] args) {
    		String s1 =  new String("bgvhvhg");
            String s2 =  new String("bgvhvhg");
            
            String str1 = new String("hjgb");
            String str2 = "hjgb";
            
            Integer i = 1;
            Integer j = 1;
    
            Integer m = 1;
            Integer n = new Integer(1);
            
            System.out.println(s1.equals(s2));
            System.out.println(str1.equals(str2));
            System.out.println(i.equals(j));
            System.out.println(m.equals(n));
    	}
    
    }
    

     执行结果:

    3.clone():创建此对象的副本,注意:它是protected的,保证只有本类才可以复制本类对象

    4.toString():返回对象的字符串表示形式。通常,toString()方法返回一个“文本表示”此对象的字符串。

    类Object的toString()方法返回一个字符串,该字符串包含类对象是实例的类的名称,at符号字符’@‘和此

    对象的哈希码的无符号十六进制表示。即:getClass().getName() + '@' + Integer.toHexString(hashCode())

    5.notify():唤醒正在等待此对象的监视器的单个线程。如果任何线程正在等待此对象,则选择其中一个被唤醒。

    选择是任意的,由程序实施自行决定。线程通过调用wait()方法之一等待对象的监视器。唤醒的线程将

    无法继续,直到当前线程放弃此对象上的锁定。唤醒的线程将以通常的方式与可能主动竞争同步此

    对象的任何其他线程竞争;例如,唤醒线程在下一个锁定此对象的线程中没有可靠的特权或劣势。

    此方法只应由作为此对象监视器的所有者的线程调用。线程以三种方式之一成为等待对象监视器的所有者:

    (1)通过执行该对象的同步实例方法。(2)通过执行在对象上同步的synchronized语句的主体。

    (3)对于{ Class}类型的对象,通过执行该类的*synchronized静态方法。

    6.notifyAll():唤醒等待此对象监视器的所有线程。 线程通过调用{ wait}方法之一等待对象的监视器。他的方法只能由

    一个线程调用,该线程是该对象监视器的所有者。

    7.wait():导致当前线程等待,直到另一个线程为此对象调用notify()方法或notifyAll()方法,或者已经过了指定的时间。

    当前线程必须拥有此对象的监视器。此方法导致当前线程将线程置于此对象的等待集中,然后放弃此对象上的任何

    和所有同步声明。因线程调度而被禁用,并且在发生以下四种情况之一之前处于休眠状态:
    (1)其他一些线程为此对象调用{notify}方法,并且线程碰巧被任意选为要唤醒的线程。

    (2)其他一些线程为此对象调用{ notifyAll}方法。

    (3)其他一些线程被中断。 (4)指定的实时数量已经或多或少。

    但是,如果*{timeout}为零,则不考虑实时时间,并且线程只是等待通知。

    8.finalize():该方法用于释放资源。因为无法确定该方法什么时候被调用,很少使用

    《三》常见问题:

    1.“==” 和equals()的区别:

    == 比较的是变量(栈)内存中存放的对象的(堆)内存地址,用来判断两个对象的地址是否相同,即是否是指相同一个对象。比较的是真正意义上的指针操作。

    equals用来比较的是两个对象的内容是否相等,由于所有的类都是继承自java.lang.Object类的,所以适用于所有对象,如果没有对该方法进行覆盖的话,调用的仍然是Object类中的方法,而Object中的equals方法返回的却是==的判断。

    由equals的源码可以看出这里定义的equals与==是等效的(Object类中的equals没什么区别),不同的原因就在于有些类(像String、Integer等类)对equals进行了重写,但是没有对equals进行重写的类(比如我们自己写的类)就只能从Object类中继承equals方法,其equals方法与==就也是等效的,除非我们在此类中重写equals。 

    对equals重写需要注意五点:

      1   自反性:对任意引用值x,x.equals(x)的返回值一定为true;
      2   对称性:对于任何引用值x,y,当且仅当y.equals(x)返回值为true时,x.equals(y)的返回值一定为true;
      3   传递性:如果x.equals(y)=true, y.equals(z)=true,则x.equals(z)=true ;
      4   一致性:如果参与比较的对象没任何改变,则对象比较的结果也不应该有任何改变;
      5   非空性:任何非空的引用值x,x.equals(null)的返回值一定为false 。

    2.为什么wait()方法是在Object类中而不是在Thread类中?

    因为我们的锁是对于对象而言的,notify(), wait()依赖于“同步锁”,而“同步锁”是对象锁持有,并且每个对象有且仅有一个!这就是为什么notify(), wait()等函数定义在Object类,而不是Thread类中的原因。

     3.wait()和sleep()的区别:

    本质区别为:

    wait():释放资源,释放锁
    sleep():释放资源,不释放锁

    但是wait()和sleep()都可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出InterruptedException(但不建议使用该方法)。在sleep()休眠时间期满后,该线程不一定会立即执行,这是因为其它线程可能正在运行而且没有被调度为放弃执行,除非此线程具有更高的优先级。wiat()必须放在synchronized block中

  • 相关阅读:
    Vue+element tree使用,当弹窗关闭时,this.$refs.tree.setCheckedKeys([])不能清空选中
    npm ERR! A complete log of this run can be found in
    Vue面试题之vue实现MVVM数据绑定
    渐变色的ie兼容
    安徽地图
    数组去重的四种方法
    EF Code First创建数据库
    Code First Migrations更新数据库结构(数据迁移)
    Bootstrap 样式大全
    C#程序中:如何向记事本中写入内容和导出内容
  • 原文地址:https://www.cnblogs.com/youdiaodaxue16/p/11429584.html
Copyright © 2020-2023  润新知