java基础(Object)

Object

一、类路径:

           java.lang.Object;

二、类属性:

       1、getClass():

                  getClass()方法返回的是对象运行时类,方法是final类型的,不可被修改,表示对象的运行时类是不可被改变的;

       2、hashCode():

                  hashCode方法返回的是对象的哈希值,它要求被多次调用后,返回的值是不能产生变化的,通常用于在HASH类存储集合中确定存储的位置,一般是与equals配合使用的;

       3、equals():

                 1、 equals方法用来判断两个对象是否相等,该方便如果没有重写,是判断对象地址是否相等;

                 2、在java的一些类型中,对equals方法进行了重写,是判断对象的属性是否相等,比如String、Integer等;

                 3、如果重写了equals方法,一般都需要重写hashCode方法,并满足一下规则:

                  equals重写规则:

                  自反性:对于任何非null的对象a,a.equals(a) 返回值必须为true;

                  对称性:   对于任何非null对象a、b;如果a.equals(b)为true,则b.equals(a)也必须为true;

                  传递性:对于任何非null对象a、b、c;如果a.equals(b)、b.equals(c)都为true,则a.equals(c)也必须为true;

                  一致性:对于任何非null对象a、b;如果a、b的属性都没有发生改变,则无论调用多少次a.equals(b),最终的返回结果都是不变的;

                  对于任何的非null对象a;a.equals(null)都应该返回false;

                  hashCode重写规则:

                  对于任何非null对象a、b;如果a.equals(b)为true,则必须保证a、b的hashCode的值必须相等;

                  对于任何非null对象a、b;如果a.equals(b)为false,则a、b的hashCode不一定相等;

                  对于任何非null对象a、b;如果a、b的hashCode相等,则a、b不一定相等;

                  常见重写方式(这里参考IDEA的方式生成)


public class Person {
    private String name;
    private int age;
    private float height;

    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;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Person person = (Person) o;
        return age == person.age &&
                Float.compare(person.height, height) == 0 &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }
}

public class Person {
    private String name;
    private int age;
    private float height;

    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;
    }

    public float getHeight() {
        return height;
    }

    public void setHeight(float height) {
        this.height = height;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (!(o instanceof Person)) return false;
        Person person = (Person) o;
        return age == person.age &&
                Float.compare(person.height, height) == 0 &&
                Objects.equals(name, person.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age, height);
    }
}

                  引申阅读:

                  我们思考,在重写equals方法 时,判断两个对象是否是同一种对象类型时,用getClass和用instanceOf有什么区别呢?

       4、clone():

                 clone方法为拷贝对象,类必须实现Cloneable接口(仅仅只是一个标记,标识此类可以被拷贝),并重写clone方法,它分为深拷贝和浅拷贝:

                 浅拷贝:只对基本类型的值进行复制,引用类型的对象,都是直接复制对象引用的:

                 深拷贝:引用类型对象本身也实现Cloneable接口,并重写了clone方法,此时对引用类型对象的拷贝也就是深拷贝了:

                 如下图中,Person类就实现了深拷贝:


public class Person implements Cloneable {
    public static class Sun implements Cloneable {
        private String name;
        private int 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
        protected Sun clone() throws CloneNotSupportedException {
            return (Sun) super.clone();
        }
    }

    private Sun sun;
    private String name;
    private int age;

    public Sun getSun() {
        return sun;
    }

    public void setSun(Sun sun) {
        this.sun = sun;
    }

    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 Person clone() throws CloneNotSupportedException {
        Person newPerson = (Person) super.clone();
        newPerson.sun = sun.clone();
        return newPerson;
    }
}

      5、toString():

                toString方法默认输出类名及哈希值,你可以重写成你想要的任何信息输出;

      6、finalize():

                finalize方法,该方法如果有重写(一般用来保证对资源的释放,如IO流(FileInputStream就重写了该方法),但是一般不推荐这么做),垃圾回收机制在第一次回收该对象的时候会调用该方法(如果没有重写该方法,对象会被直接回收),当在第二次触发垃圾回收时,不会再调用该方法,会直接回收对象(如果你在该方法中,强行给该对象增加强引用,则可以救活该对象);

      7、wait()、wait(long)、notify()、notifyAll():

                这几个方法放在一起讲,是因为他们是相互协作的,下面详细介绍:

                1、这三个方法,一般是用在多线程的生产者和消费者模式中,生产者不停的生产,消费者不停的消费,必须考虑线程安全问题,所以他们都会在同步代码块当中(如果不在同步代码块中使用,会抛出IllegalMonitorStateException异常);

                2、这三个方法一般都是放在循环语句当中,用于循环生产和消费;

                3、生产者生产产品之后,调用wait()方法使线程进入等待状态,或者调用wati(long)方法,让线程进入等待状态(如果超过一定时间,线程将自动被唤醒), 而调用wait后当前生产者(消费者)线程将释放锁;

                4、生产者在调用wait之前,必须调用notify或者notifyAll唤醒其它线程,其它线程被唤醒后,会共同竞争锁,拿到锁的线程将进行消费(或生产);

                典型的应用如下所示:

/**
 * 生产者
 */
class Producter extends Thread {
    @Override
    public void run() {
        while (run) {
            synchronized (queue) {
                while (queue.size() >= MAX_CAPACITY * 2) {
                    try {
                        System.out.println("缓冲队列已满,等待消费");
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    String string = UUID.randomUUID().toString();
                    queue.put(string);
                    System.out.println("生产:" + string);
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 生产完后立马通知消费
                queue.notifyAll();//通知生产者和消费者
            }
        }
    }
}
/**
 * 消费者
 */
class Consumer extends Thread {
    @Override
    public void run() {
        while (run) {
            synchronized (queue) {
                while (queue.isEmpty()) {
                    try {
                        System.out.println("队列为空,等待生产");
                        queue.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }

                try {
                    System.out.println("消费:" + queue.take());
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                // 消费后立马通知生产
                queue.notifyAll();//通知生产者和消费者
            }
        }
    }
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值