面向对象-object类

Object类:

? 面向对象-object类

自带一个无参构造。

1、clone方法:

? 保护方法,实现对象的浅复制(浅拷贝),只有实现了Cloneable接口才可以调用这个方法,否则会抛出CloneNotSupportedException异常

public class CloneTest implements Cloneable {

    private String name;

    public CloneTest(String name) {
        this.name = name;
    }

    public CloneTest() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }


    public String myToString() {
        return "CloneTest{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }

    public static void main(String[] args) {
        try{
            CloneTest cloneTest1=new CloneTest("geng");
            CloneTest cloneTest2=(CloneTest) cloneTest1.clone();
            System.out.println(cloneTest1+" "+cloneTest2);
            System.out.println(cloneTest1.myToString()+" "+cloneTest2.toString());
        }
        catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
    }
}

面向对象-object类

2、getClass方法:

? final方法,返回Class类型对象,反射来获取该对象

3、toString方法:

? 常用方法

? 该方法一般子类都有覆盖,用来获取对象的信息。当我们直接输出对象的时候,默认输出一个该对象在堆内存中的值,如果要输出该对象的内容则要覆盖写一个toString方法。

? 正是因为所有的类都继承自Object类,我们才可以实现两个不同类型对象的拼接。

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

4、finalize方法:

? 该方法用于释放资源,很少使用(当垃圾回收机制发现没有任何引用指向该对象,就会执行该方法)参考C++中的析构方法

public class CloneTest implements Cloneable {

    private String name;

    public CloneTest(String name) {
        this.name = name;
    }

    public CloneTest() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }

    @Override
    protected void finalize() throws Throwable {
        System.out.println("垃圾回收了");
        super.finalize();

    }

    public String myToString() {
        return "CloneTest{" +
                "name=‘" + name + ‘\‘‘ +
                ‘}‘;
    }

    public static void main(String[] args) {
        try{
            CloneTest cloneTest1=new CloneTest("geng");
            CloneTest cloneTest2=(CloneTest) cloneTest1.clone();
            cloneTest1=null;
            cloneTest2=null;
            //我们不知道啥时候进行垃圾回收,就强制进行释放空间
            System.gc();
        }
        catch (CloneNotSupportedException e){
            e.printStackTrace();
        }
    }
}

面向对象-object类

5、equals方法:

? 常用方法

? 比较对象的内容是否相等,基本数据类型使用的是==,引用数据类型使用equals来进行比较

? ==运算符:

? 1、可以使用在基本数据类型和引用数据类型中

? 2、如果是比较基本数据类型,是比较两个变量的数据是否相等(允许自动类型提升)

? 3、如果是比较引用数据类型,是比较对象的地址值

? (比较堆内存中的值,基本数据类型存放的是数据的值,引用数据类型存放的是引用对象的 地址值)

import java.sql.PseudoColumnUsage;

public class test02 {
    public static void main(String[] args){
        int a=10;
        double b=10.0;
        //存在一个类型提升a从int变成double
        System.out.println(a==b);
        //注意基本类型的数据提升是不包括Boolean的
        boolean c=false;
        //直接报错
        //System.out.println(1==c);
        char d=10;
        System.out.println(b==d);

        String str1="geng";
        String str2="geng";
        System.out.println(str1==str2);//true
        String str3=new String("geng");
        String str4=new String("geng");
        System.out.println(str3==str4);//false
    }
}

? 那为什么我们String类型的变量会出现这种情况呢?

? 常量池:

? 常量池(constant pool)指的是在编译期被确定,并被保存在已编译的.class文件中的一 些数据。它包括了关于类、方法、接口等中的常量,也包括字符串常量。Java为了提高性 能,静态字符串(字面量/常量/常量连接的结果)在常量池中创建,并尽量使用同一个对 象,重用静态字符串。对于重复出现的字符串字面量,JVM会首先在常量池中查找,如果常 量池中存在即返回该对象。

? 首先我们需要知道String是引用数据类型。当我们使用String str1="geng"的时候,我们 就会从常量池中获取到该对象,然后赋值给str1。剩下的str3 str4是从栈中定义对象,所以 两种是有本质区别的,一个是方法区(静态区)中的对象,一个是栈中的对象。

? ===运算符:

? 不允许自动类型提升(类型不同直接返回false)

? equals方法:

public class Person {
    private String name;
    private int age;
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public Person(Person person){
        this.name=person.getName();
        this.age=person.getAge();
    }
    public String myToString() {
        return this.name+" "+this.age;
    }
    public Person() {
    }


    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 void eat(){
        System.out.println("吃饭");
    }
    public void sleep(){
        System.out.println("睡觉");
    }
}
Person person1=new Person("1",2);
Person person2=new Person(person1);
System.out.println(person1.toString()+" "+person2.toString());
System.out.println(person1.myToString()+" "+person2.myToString());
System.out.println(person1.equals(person2));

面向对象-object类

? 我们查看源代码发现:

public boolean equals(Object obj) {
    return (this == obj);
}

? 哈哈哈哈,可以发现我们的equals方法不充写的情况下就是==,String类型之所以可以使用equals比较值,是因为他重写了equals方法。

6、hashCode方法:

? 该方法用于哈希查找,重写了equals方法一般都要重写hashcode方法,这个方法在一些具有哈希功能的Collection中可以用到

7、wait方法:

? wait方法就是使当前线程等待该对象的锁,当前线程必须是该对象的拥有者,也就是具有该对象的锁。wait()方法一直等待,直到获得锁或者被中断。wait(long timeout)设定一个超时间隔,如果在规定时间内没有获得锁就返回。

调用该方法后当前线程进入睡眠状态,直到以下事件发生。

其他线程调用了该对象的notify方法。

其他线程调用了该对象的notifyAll方法。

其他线程调用了interrupt中断该线程。

时间间隔到了。

此时该线程就可以被调度了,如果是被中断的话就抛出一个interruptedException异常。

8、notify方法:

? 该方法唤醒在该对象上等待的某个线程

9、notifyAll方法:

? 该方法唤醒在该对象上等待的所有线程。

面向对象-object类

上一篇:Mike and gcd problem CodeForces - 798C (贪心思维+数论)


下一篇:Netty:数据处理流程