zoukankan      html  css  js  c++  java
  • Java基础--常用API--java.lang.Object

    一、简述

      1、Object类是所有类的父类,即直接或间接的继承java.lang.Object类。省略了extends Object。

      2、方法

        (1)protected native Object clone() throws CloneNotSupportedException; //创建并返回一个对象的副本。

        (2)public String toString();  //返回一个字符串,一般需要重写。

        (3)public final native Class<?> getClass();  //返回对象在运行时的类的类型

        (4)public boolean equals(Object obj);  //用来判断调用equals对象与参数对象obj是否为同一个对象,一般需重写。

        (5)public native int hashCode(); //返回对象的哈希码,可用于哈希查找,减少equals比较的次数,一般重写equals方法后也要重写hashcode方法。

        (6)protected void finalize() throws Throwable { }; //该方法用于释放资源,无法确定该方法什么时候被调用。

        (7)public final native void wait(long timeout) throws InterruptedException; //使当前线程等待锁,直到获取锁或被中断,timeout指的是最长等待时间。

        (8)public final native void notify(); //用于随机唤醒该对象上等待的某个线程。

        (9)public final native void notifyAll(); //用于唤醒该对象上等待的所有线程。

      3、由于getClass()、notify()、notifyAll()、wait()等方法被final修饰,所以不能被重写。

    二、Clone()

      1、clone()方法作用是返回一个Object对象的复制,且复制的对象是一个新的对象。

      

      2、使用clone()方法时,需要实现Cloneable接口,否则会抛出异常(CloneNotSupportedException)。

      3、分类:浅复制(Shallow Clone)与深复制(Deep Clone)

        (1)浅复制:复制后的对象的所有变量都与原有对象的值相同,且所有对其他对象的引用仍指向原来的对象。简单的讲,对于基本类型,复制的是数据,对于引用类型,复制的是数据的地址。即浅复制复制当前对象,不复制当前对象中的引用对象。

          注意一个坑:对于引用类型,复制的是数据的地址(通过地址访问对象的真实数据)。若通过地址来修改对象,那么原有对象以及复制的对象均会修改相应的值。但若是修改了地址(比如new了一个对象,则地址发生改变,而原有的对象并未发生改变),则只有被修改的对象才会发生改变。

        (2)深复制:指的是完全复制,将当前对象整体复制,并创建一个新的对象保存。即深复制复制当前对象,且复制当前对象中的引用对象。简单的讲,深复制在浅复制的基础上,将引用类型再复制一份,其中引用类型需要实现Cloneable接口(如下例中的People类实现了Cloneable接口)。

          注意一个坑:只有实现了Cloneable接口,才能调用clone()方法。

    /**
     * 引用类型,用于测试浅复制与深复制的差别。 若只是浅复制,不用实现Clonable接口。 若是深复制,则要实现Cloneable接口以及clone方法。
     */
    class People implements Cloneable {
        private String name;
        private int age;
    
        public People(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "People [name=" + name + ", age=" + age + "]";
        }
    
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }
    
    /**
     * 浅复制
     */
    class ShallowCloneDemo implements Cloneable {
        private People people;
        private String sex;
    
        public ShallowCloneDemo(People people, String sex) {
            this.people = people;
            this.sex = sex;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public People getPeople() {
            return people;
        }
    
        public void setPeople(People people) {
            this.people = people;
        }
    
        @Override
        protected Object clone() {
            try {
                return (ShallowCloneDemo) super.clone();
            } catch (CloneNotSupportedException e) {
                System.out.println("Shallow Clone Error");
                return null;
            }
        }
    
        @Override
        public String toString() {
            return "ShallowCloneDemo [people=" + people + ", sex=" + sex + "]";
        }
    }
    
    /**
     * 深复制
     */
    class DeepCloneDemo implements Cloneable {
        private People people;
        private String sex;
    
        public DeepCloneDemo(People people, String sex) {
            this.people = people;
            this.sex = sex;
        }
    
        public People getPeople() {
            return people;
        }
    
        public void setPeople(People people) {
            this.people = people;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        @Override
        protected Object clone() {
            DeepCloneDemo obj = null;
            try {
                obj = (DeepCloneDemo) super.clone();// 浅复制
                obj.people = (People) this.getPeople().clone();// 需要克隆引用类型
            } catch (CloneNotSupportedException e) {
                System.out.println("Deep Clone Error");
                return null;
            }
            return obj;
        }
    
        @Override
        public String toString() {
            return "DeepCloneDemo [people=" + people + ", sex=" + sex + "]";
        }
    
    }
    
    /**
     * 测试类,用于测试浅复制与深复制
     */
    public class Test {
        public static void main(String[] args) {
            System.out.println("普通实例化一个ShallowCloneDemo:");
            ShallowCloneDemo shallowCloneDemo1 = new ShallowCloneDemo(new People("rick", 18), "man");
            System.out.println("实例化完成");
            System.out.println();
    
            System.out.println("通过clone()方法浅复制克隆一个ShallowCloneDemo:");
            System.out.println("Start Shallow Cloning");
            ShallowCloneDemo shallowCloneDemo2 = (ShallowCloneDemo) shallowCloneDemo1.clone();
            System.out.println("Shallow Clone End");
            System.out.println();
    
            System.out.println("输出原有对象以及浅复制克隆对象的值:");
            System.out.println(shallowCloneDemo1);
            System.out.println(shallowCloneDemo2);
            System.out.println();
    
            System.out.println("对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:");
            shallowCloneDemo1.getPeople().setName("tom");
            shallowCloneDemo2.getPeople().setAge(20);
            shallowCloneDemo1.setSex("woman");
            System.out.println(shallowCloneDemo1);
            System.out.println(shallowCloneDemo2);
            System.out.println("结果显示,浅复制对象会随着原有对象一起修改。");
            System.out.println("这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值");
            System.out.println();
    
            System.out.println("普通实例化一个DeepCloneDemo:");
            DeepCloneDemo deepCloneDemo1 = new DeepCloneDemo(new People("rick", 18), "man");
            System.out.println("实例化完成");
            System.out.println();
    
            System.out.println("通过clone()方法深复制克隆一个DeepCloneDemo:");
            System.out.println("Start Deep Cloning");
            DeepCloneDemo deepCloneDemo2 = (DeepCloneDemo) deepCloneDemo1.clone();
            System.out.println("Deep Clone End");
            System.out.println();
    
            System.out.println("输出原有对象以及深复制克隆对象的值:");
            System.out.println(deepCloneDemo1);
            System.out.println(deepCloneDemo2);
            System.out.println();
    
            System.out.println("对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:");
            deepCloneDemo1.getPeople().setName("tom");
            deepCloneDemo2.getPeople().setAge(20);
            deepCloneDemo1.setSex("woman");
            System.out.println(deepCloneDemo1);
            System.out.println(deepCloneDemo2);
            System.out.println("结果显示,深复制时对象是独立的,互不干扰。");
            System.out.println("这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值");
        }
    }
    /*
    测试结果:
    普通实例化一个ShallowCloneDemo:
    实例化完成
    
    通过clone()方法浅复制克隆一个ShallowCloneDemo:
    Start Shallow Cloning
    Shallow Clone End
    
    输出原有对象以及浅复制克隆对象的值:
    ShallowCloneDemo [people=People [name=rick, age=18], sex=man]
    ShallowCloneDemo [people=People [name=rick, age=18], sex=man]
    
    对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:
    ShallowCloneDemo [people=People [name=tom, age=20], sex=woman]
    ShallowCloneDemo [people=People [name=tom, age=20], sex=man]
    结果显示,浅复制对象会随着原有对象一起修改。
    这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值
    
    普通实例化一个DeepCloneDemo:
    实例化完成
    
    通过clone()方法深复制克隆一个DeepCloneDemo:
    Start Deep Cloning
    Deep Clone End
    
    输出原有对象以及深复制克隆对象的值:
    DeepCloneDemo [people=People [name=rick, age=18], sex=man]
    DeepCloneDemo [people=People [name=rick, age=18], sex=man]
    
    对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:
    DeepCloneDemo [people=People [name=tom, age=18], sex=woman]
    DeepCloneDemo [people=People [name=rick, age=20], sex=man]
    结果显示,深复制时对象是独立的,互不干扰。
    这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值
    */

    三、toString、getClass

      1、Object 类的 toString 方法返回一个字符串,该字符串由类名、标记符“@”和此对象哈希码的无符号十六进制表示组成

      2、Object 类的getClass()方法返回一个对象的类名。

    四、equals、hashcode

      1、Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象(即是否占据同一个内存)。对于内容相同但内存不同的对象,返回false。需要进行重写,并重写比较规则,才能使其为true。

      2、Object的hashcode()方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。

    五、==和equals的区别是什么?

      1、==对于基本类型,比较的是值,对于引用类型,比较的引用变量的堆内存地址。

      2、equals未重写时等价于==,一般重写后用来比较两个对象的内容是否相等。

    六、hashCode() 与 equals() 的关系?

      1、hashcode()的作用用于获取哈希码(散列码),其返回一个int整数,用于确定对象在哈希表中的索引位置。


      2、equals相同的两个对象的hashCode必定相同。


      3、hashCode相同的两个对象的equal不一定相同。


      4、equals重写时,hashcode一般需重写。hashcode默认为堆中对象产生的独特值,若未重写hashcode,那么即使两个对象指向同一个数据,hashcode值也不会相等。


      5、hashcode与equals在HashSet中的应用,当对象加入HashSet时,先由hashcode计算对象的散列值,若相等,则比较equals,若equals比较仍相等(即为相同对象),则对象不会加入到HashSet中。若equals比较不等,则将对象重新散列到其他位置。通过减少equals比较次数,可以提高执行速度。

  • 相关阅读:
    怎么把创业的风险降到最低
    反思:创业一开始并不需要重量级的产品
    口头承诺不如白纸黑字 技术大牛曹政(前4399核心员工)期权被坑的那些事
    idea配置tomcat去启动web项目
    Closeable释放资源
    Spring的SchedulingConfigurer实现定时任务
    thymeleaf js绑定多个变量参数
    Mysql concat() group_concat()用法
    枚举
    lambda之美
  • 原文地址:https://www.cnblogs.com/l-y-h/p/10906499.html
Copyright © 2011-2022 走看看