2021-09-10 Object类

Object类

JDK类库的根类:Object

类中方法所有子类通用,所有类默认继承Object,

1. 常用方法

查询所有方法:

  1. 查源代码(C:\Program Files\Java\jdk1.8.0_301\src\java\lang\object.java):麻烦、代码难懂
  2. 查阅Java类库帮助文档

什么是API?

API = Application Program Interface 应用程序编程接口

SUN公司提前写好的,整个JDK的类库,就是一个JavaSE的API

每个API都配置帮助文档(https://docs.oracle.com/javase/8/docs/api/)

常用方法

protected Object clone()		//负责对象克隆
boolean	equals(Object obj)		//判断两对象是否相等
protected void	finalize()		//负责调用垃圾回收器
int	hashCode()		//获取对象哈希值
String toString()		//讲对象换成字符串形式

2. toString()方法

源码

public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
//类名@对象的内存地址转换为十六进制的形式

作用

将一个Java对象转换成字符串表示形式,建议所有子类都重写toString()方法。

练习

package com.comclass;

import com.comclass.demo01.MyTime;

public class Application {
    public static void main(String[] args) {
        MyTime myTime = new MyTime(1990,11,1);
        String s1 = myTime.toString();
        //重写前,不简洁,不容易阅读,日期对象转换成字符串后还希望看见日期
        System.out.println(s1);     //com.comclass.demo01.MyTime@1b6d3586
    }
}
/*
package com.comclass.demo01;

public class MyTime {
    int year;
    int month;
    int day;

    public MyTime(){

    }
    public MyTime(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
}
 */

重写前,toString()方法不简洁,不容易阅读,日期对象转换成字符串后还希望看见日期。

所以需要重写,原则要简洁、翔实、易阅读

package com.comclass;

import com.comclass.demo01.MyTime;

public class Application {
    public static void main(String[] args) {
        MyTime myTime = new MyTime(1990,11,1);
        String s1 = myTime.toString();

        System.out.println(s1);     //1990年11月1日
    }
}

/*
package com.comclass.demo01;

public class MyTime {
    int year;
    int month;
    int day;

    public MyTime(){

    }
    public MyTime(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //重写

    @Override
    public String toString() {
        return this.year+"年"+this.month+"月"+this.day+"日";
    }
}

 */

注意:输出引用的时候,会自动调用该引用的toString()方法。

System.out.println(s1);     //1990年11月1日

以后toString()都自己重写

3. equals()方法

源码

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

作用

判断两个对象是否相等

Object类中默认使用“==”判断两个对象是否相等,而双等号判断的是对象内存地址,所以要判断对象内容,需要子类重写equsals();

package com.comclass;

import com.comclass.demo02.MyTime;
import sun.security.mscapi.CPublicKey;

public abstract class Application {
    public static void main(String[] args) {
        //判断基本数据,双等号判断a,b中的100是否相等
        int a = 100;
        int b = 100;
        System.out.println(a == b); //true
        //判断引用类型(对象),双等号比较的是对象内存地址
        MyTime myTime1 = new MyTime(2008,8,8);      //MyTime myTime1 = 0x1234
        MyTime myTime2 = new MyTime(2008,8,8);      //MyTime myTime2 = 0x3456
        MyTime myTime3 = new MyTime(2008,8,9);
        System.out.println(myTime1 == myTime2);     //false
        //Object类给的equals方法不够用
        //重写前
        //System.out.println(myTime1.equals(myTime2));       //false
        //重写后
        String s = "hhhh";
        System.out.println(myTime1.equals(myTime2));    //true
        System.out.println(myTime1.equals(s));          //false对象类型不同
        System.out.println(myTime1.equals(myTime3));    //false
    }
}

/*
package com.comclass.demo02;

public class MyTime {
    int year;
    int month;
    int day;

    public MyTime(){

    }
    public MyTime(int year, int month, int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
    //重写

    public boolean equals(Object obj){
        if(obj instanceof MyTime){
            MyTime mt = (MyTime)obj;
            if(this.year == mt.year && this.month == mt.month && this.day == mt.day){
                return true;
            }
        }
        return false;
    }

}

 */

改良的equals()方法

//改良
public boolean equals(Object obj){
        if(obj == null){
            return false;
        }
        if(!(obj instanceof MyTime)){
            return false;
        }
        if(this == obj){        //内存地址相同指向同一对象
            return true;
        }
        MyTime mt = (MyTime)obj;
        if(this.year == mt.year && this.month == mt.month && this.day == mt.day){
           return true;
       }
        return false;
}

package com.comclass;

import com.comclass.demo02.MyTime;
import sun.security.mscapi.CPublicKey;

public abstract class Application {
    public static void main(String[] args) {
        //判断基本数据,双等号判断a,b中的100是否相等
        int a = 100;
        int b = 100;
        System.out.println(a == b); //true
        //判断引用类型(对象),双等号比较的是对象内存地址
        MyTime myTime1 = new MyTime(2008,8,8);      //MyTime myTime1 = 0x1234
        MyTime myTime2 = new MyTime(2008,8,8);      //MyTime myTime2 = 0x3456
        MyTime myTime3 = new MyTime(2008,8,9);
        MyTime myTime4 = null;
        System.out.println(myTime1 == myTime2);     //false
        //Object类给的equals方法不够用
        //重写前
        //System.out.println(myTime1.equals(myTime2));       //false
        //重写后
        String s = "hhhh";
        System.out.println(myTime1.equals(myTime2));    //true
        System.out.println(myTime1.equals(s));          //false对象类型不同
        System.out.println(myTime1.equals(myTime3));    //false
        System.out.println(myTime1.equals(myTime4));    //false
    }
}

超级改良

//超级改良
public boolean equals(Object obj){
        if(obj == null || !(obj instanceof MyTime)){
            return false;
        }
        if(this == obj){        //内存地址相同指向同一对象
            return true;
        }
        MyTime mt = (MyTime)obj;
        return this.year == mt.year && this.month == mt.month && this.day == mt.day;
}

String类有没有重写toString()方法和equals()方法?

重写了

比较两个字符串不能使用双等号,必须用equals()方法

String类有没有重写toString方法?

重写了

Java中基本数据类型使用""=="判断相等

Java中引用数据类型使用equals判断相等

练习

package com.comclass;

import java.util.Locale;

public abstract class Application {
    public static void main(String[] args) {
        //一般创建字符串
        String s1 = "hello";
        String s2 = "abc";

        //实际上String作为一个类
        //存在构造方法
        String s3 = new String("Test1");
        String s4 = new String("Test1");
        //new两次,内存地址不同
        System.out.println(s3 == s4);   //false
        //比较字符串,不能使用双等号,必须用equals()
        //String重写了equals()方法
        System.out.println(s3.equals(s4));  //true


        //String有没有重写toString
        String x = new String("动力节点");
        //没重写结果为:类名@十六进制地址
        //重写结果为:字符串
        System.out.println(x.toString());   //动力节点
        System.out.println(x);              //动力节点
        //输出字符串x,默认调用toString,.toSting可以不写
    }
}
package com.comclass.demo04;

public class Student {
    int id;
    String school;
    public Student(){

    }

    public Student(int id, String school) {
        this.id = id;
        this.school = school;
    }

    //重写toString
    @Override
    public String toString() {
        return "学号:" + id +", 所在学校:" + school;
    }
    //重写equals
    public boolean equals(Object obj){
        if(obj == null || !(obj instanceof Student)){
            return false;
        }
        if(this == obj){
            return true;
        }
        Student st = (Student) obj;
        return st.id == this.id && this.school.equals(st.school);
    }

}
/*
package com.comclass;

import com.comclass.demo04.Student;

import java.util.Locale;

public abstract class Application {
    public static void main(String[] args) {
        Student s1 = new Student(203,"TJ");
        Student s2 = new Student(203,"SJ");
        Student s3 = new Student(203,"TJ");

        System.out.println(s1.toString());
        System.out.println(s2.toString());
        System.out.println(s1.equals(s2));  //false
        System.out.println(s1 == s3);       //false
        System.out.println(s1.equals(s3));  //true
    }
}
 */

new出来的字符串不可以用双等号判断,但是直接赋值的字符串可以用双等号判断。

package com.comclass.demo04;

public class Student {
    int id;
    String school;
    public Student(){

    }

    public Student(int id, String school) {
        this.id = id;
        this.school = school;
    }

    //重写toString
    @Override
    public String toString() {
        return "学号:" + id +", 所在学校:" + school;
    }
    //重写equals
    public boolean equals(Object obj){
        if(obj == null || !(obj instanceof Student)){
            return false;
        }
        if(this == obj){
            return true;
        }
        Student st = (Student) obj;
        //return st.id == this.id && this.school.equals(st.school);
        return st.id == this.id && this.school == st.school;
    }

}
/*
package com.comclass;

import com.comclass.demo04.Student;

public abstract class Application {
    public static void main(String[] args) {
        Student s1 = new Student(203,"TJ");
        Student s2 = new Student(203,"SJ");
        Student s3 = new Student(203,"TJ");
        Student s4 = new Student(203,new String("TJ"));

        System.out.println(s1.toString());
        System.out.println(s2.toString());
        System.out.println(s1.equals(s2));  //false
        System.out.println(s1 == s3);       //false
        System.out.println(s1.equals(s3));  //true
        System.out.println(s1.equals(s4));  //false
    }
}
 */
package com.comclass;

import com.comclass.demo04.Student;
import com.comclass.demo05.Address;
import com.comclass.demo05.User;

public abstract class Application {
    public static void main(String[] args) {
        //Address addr = new Address("上海", "四平路", "200092");
        //User u = new User("GY",addr);
        User u1 = new User("GY", new Address("上海", "四平路", "200092"));
        User u2 = new User("GY",new Address("上海", "四平路", "200092"));
        User u3 = new User("GY",new Address("上海", "彰武路", "200093"));
        System.out.println(u1.equals(u2));  //true
        System.out.println(u1.equals(u3));  //false
    }
}
/*
package com.comclass.demo05;

public class User {
    String name;    //保存的内存地址
    Address addr;

    public User(){    }
    public User(String name, Address addr){
        this.addr = addr;
        this.name = name;
    }
    public boolean equals(Object obj){
        if(obj == null || !(obj instanceof User)) return false;
        if(obj == this){
            return true;
        }
        User u = (User) obj;
        return this.name.equals(u.name) && this.addr.equals(u.addr);
    }
}
 */
/*
package com.comclass.demo05;

public class Address {
    String city;
    String street;
    String zipcode;
    public Address(){

    }
    public Address(String city, String street, String zipcode) {
        this.city = city;
        this.street = street;
        this.zipcode = zipcode;
    }

    @Override
    public boolean equals(Object obj) {
        if(obj == null || !(obj instanceof Address)) return false;
        if(obj == this){
            return true;
        }
        Address addr = (Address) obj;
        return this.city.equals(addr.city) &&
                this.street.equals(addr.street) &&
                this.zipcode.equals(addr.zipcode);
    }
}

 */

4. finalize()方法

源码

protected void finalize() throws Throwable{
    
}

protected修饰的,只有方法体

无需手动调用

JVM的垃圾回收器回收垃圾时自动调用,GC负责调用

执行时机:一个Java对象即将被垃圾回收器回收时

是SUN为程序员准备的垃圾销毁时机,想在垃圾销毁时执行代码可以写在finalize内

类似于静态代码块,在类加载时执行,且执行一次,是类加载时机。

Java的垃圾回收器不是轻易启动的,垃圾少,时间不到等不启动,可以多造点垃圾(for循环),或者建议垃圾回收器启动代码

System.gc()

-----建议归建议,人家并不一定会启动,只是启动的概率高了一些

作用

是SUN为程序员准备的垃圾销毁时机,想在垃圾销毁时执行代码可以写在finalize内。

练习

package com.comclass;
import com.comclass.demo06.Person;

public abstract class Application {
    public static void main(String[] args) {
//        Person p = new Person();
//        //把p变成垃圾
//        p = null;
//        for (int i = 0; i < 10000000; i++) {
//            Person q = new Person();
//            q = null;
//        }
        //把p变成垃圾

        for (int i = 0; i < 10; i++) {
            Person q = new Person();
            q = null;
        }
        System.gc();
    }
}
/*
package com.comclass.demo06;

public class Person {
    @Override
    protected void finalize() throws Throwable {
        System.out.println(this+"即将被销毁");
    }
}

 */

5. hashCode() 方法

源码

public native int hashCode();

不是抽象方法,带有native关键字,底层调用C++程序,返回int类型值

作用

返回哈希值:一个Java对象的内存地址,经过哈希算法得出的哈希值,所以结果可以等同看作一个对象的内存地址。

package com.comclass;

import com.comclass.demo07.MyClass;

public abstract class Application {
    public static void main(String[] args) {
        Object o = new Object();
        int hashCodeValue = o.hashCode();
        System.out.println(hashCodeValue);      //460141958
        MyClass mc = new MyClass();
        int h2 = mc.hashCode();
        System.out.println(h2);     //1163157884
        System.out.println(new MyClass().hashCode());   //1956725890

    }
}
/*
package com.comclass.demo07;

public class MyClass {

}

 */

6. clone()方法

源码

protected Object clone()
                throws CloneNotSupportedException

底层调用C++,深克隆,浅克隆

作用

创建并返回一个对象的克隆

for any object x, the expression:

   x.clone() != x

will be true, and that the expression:

 x.clone().getClass() == x.getClass()

will be true, but these are not absolute requirements. While it is typically the case that:

 x.clone().equals(x)

will be true, this is not an absolute requirement.

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值