自学java (day24):Object

/*
* 1、JDK类库的根类:Object

    1.1、这个老祖宗类中的方法我们要研究一下,因为这些方法都是所有子类通用的。任何一个类默认继承Object。就算没有直接继承,最后也会间接继承。

    1.2、Object类中有哪些常用的方法?
        去哪里找这些方法呢?
            第一种方法:去源代码中,(但是这种方式比较麻烦,源代码也比较难)
            第二种方法:去查阅java类库的帮助文档。

        什么是API?
            应用程序编程接口。
            整个JDK的类库就是一个javase的API。
            每一个API都会配置一套API帮助文档。

        现在只需要知道如下几个方法即可:
            protected Object clone() //负责对象克隆的
            int hashCode()  //获取对象哈希值的一个方法
            boolean equals (Object obj)  //判断两个对象是否相等
            String  toString() //将对象转换成字符串形式
            protected void finalize()  //垃圾回收器负责调用的方法

*/

/**
 *  关于Object类中的toString()方法
 *
 *      1、源代码
 *          public String toString(){
 *              return this.getClass().getName() + "@" + Integer.toHexString(hashCode());
 *          }
 *          源代码中toString()方法的默认实现是:
 *              类名@对象的内存地址转换为十六进制的形式
 *
 *      2、设计toString()方法的目的是什么?
 *          toString()方法的作用是什么?
 *              toString()方法的设计目的是:通过调用这个方法可以将一个”java对象“转换成”字符串表示形式“
 *
 *      3、开发java语言的时候建议所有子类都去重写toString()方法
 *      toString()方法应该是一个简单的、详实的、易阅读的
 */
public class Api {
    public static void main(String[] args){
        MyTime mt=new MyTime(2200,5,6);
        String s1=mt.toString();

        //MyTime类重写toString()方法之前
        System.out.println(s1);//MyTime@b4c966a

        //MyTime类重写toString()方法之后
        System.out.println(s1);//2200年5月6日

        //系统自动调用toString()方法,在引用的时候
    }
}

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

    //构造方法(没有返回值)
    public MyTime(){

    }

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

    //getter AND setter

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    //重写toString()方法

    @Override
    public String toString() {
        return this.year + "年" + this.month + "月" + this.day + "日";
    }
}
/**
 * g关于Object类中的equals方法
 *      1、equals方法的源代码:
 *          public boolean equals(Object obj){
 *              return (this == obj);
 *          }
 *          以上方法是Object类的默认实现
 *
 *      2、设计equals方法的目的是什么?
 *          以后编程的过程中,都要通过equals方法来判断两个对象是否相等
 *          equals方法是判断两个方法是否相等的
 *
 *      3、我们需要研究Object类给的这个默认的equals方法够不够用!!!!
 *          不够用,必须重写equals方法
 *
 */

equals



/*
                现在只需要知道如下几个方法即可:
            protected Object clone() //负责对象克隆的
            int hashCode()  //获取对象哈希值的一个方法
            boolean equals (Object obj)  //判断两个对象是否相等
            String  toString() //将对象转换成字符串形式
            protected void finalize()  //垃圾回收器负责调用的方法
 */

import java.util.Objects;

/**
 * g关于Object类中的equals方法
 *      1、equals方法的源代码:
 *          public boolean equals(Object obj){
 *              return (this == obj);
 *          }
 *          以上方法是Object类的默认实现
 *
 *      2、设计equals方法的目的是什么?
 *          以后编程的过程中,都要通过equals方法来判断两个对象是否相等
 *          equals方法是判断两个方法是否相等的
 *
 *      3、我们需要研究Object类给的这个默认的equals方法够不够用!!!!
 *          不够用,必须重写equals方法
 *
 */
public class Test {
    public static void main(String[] args) {
        MyTime t1 = new MyTime(2001, 5, 8);
        MyTime t2 = new MyTime(2000, 5, 8);

        String s1=t1.toString();
        System.out.println(s1);

        //重写Object equals方法之前(比较的是两个对象的内存地址)
       // boolean flag=t1.equals(t2);
      //  System.out.println(flag);

        //重写Object equals方法之后
        boolean flag=t1.equals(t2);//t1和t2比较
        System.out.println(flag);
    }
}

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

    //构造方法(没有返回值)
    public MyTime(){

    }

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

    //getter AND setter

    public int getYear() {
        return year;
    }

    public void setYear(int year) {
        this.year = year;
    }

    public int getMonth() {
        return month;
    }

    public void setMonth(int month) {
        this.month = month;
    }

    public int getDay() {
        return day;
    }

    public void setDay(int day) {
        this.day = day;
    }

    /**
    //重写equals方法
    //怎么重写?
    public boolean equals(Object obj){
        //当年月日相同表示两个对象相同
        //获取第一个日期的年月日
        int year1=this.year;
        int month1=this.month;
        int day1=this.day;
        //获取第二个日期的年月日
        if (obj instanceof MyTime){
            MyTime t=(MyTime)obj;
            int year2=t.year;
            int month2=t.month;
            int day2=t.day;
            //开始比较
            if(year1==year2&&month1==month2&&day1==day2){
                return true;
            }
        }
             return false;
    }
     */

    //s生成toString方法
    @Override
    public String toString() {
        return "MyTime{" + "year=" + year + ", month=" + month + ", day=" + day + '}';
    }


    @Override
    public int hashCode() {
        return Objects.hash(year, month, day);
    }

    //生成equals方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        MyTime myTime = (MyTime) o;
        return year == myTime.year && month == myTime.month && day == myTime.day;
    }
}
toString
/**
 * 1、java语言当中的字符串String有没有重写toString方法,有没有重写equals方法。
        String类已经重新equals方法,比较字符串必须使用equals方法
            equals是通用的
    2、String类有没有重写toString方法
        String类已经重写了 toString()方法

    3、java中什么类型的数据使用“==”判断,什么类型的数据使用“equals”判断::基本数据类型使用“==”,引用数据类型使用“equals方法”是否相等。

 */
public class toString {
    public static void main(String[] args){

        //大部分情况下都是使用这种方法创建字符串
        String s1="hello";
        String s2="abc";

        //实际上String也是一个类,不属于基本数据类型
        //既然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());//动力节点
        //.toString可以省略
        System.out.println(x);//动力节点

    }
}

equals

/**
 *      重写equals方法必须彻底  所有的类里都要重写
 */
public class equals {
    public static void main(String[] args){
        Student s1=new Student(36,"北京大学");
        Student s2=new Student(36,"北京大学");
        System.out.println(s1==s2);//false
        System.out.println(s1.equals(s2));//true
    }
}

class Student{
    //学号
    private int no;
    //所在学校
    private String school;
    //重写toString方法
    public String toString(){
        return "学号"+no+"所在学校"+school;
    }
    //构造方法
    public Student(){

    }

    public Student(int no,String school){
        this.no=no;
        this.school=school;
    }
    //getter and setter

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getSchool() {
        return school;
    }

    public void setSchool(String school) {
        this.school = school;
    }

    //重写equals方法
    //等一个学生的学号和学校相同时表示是同一个学生
    public boolean equals(Object obj){
        if((obj==null)||!(obj instanceof Student))
            return  false;
        if(this==obj)
            return  true;
        Student s=(Student) obj;
        return this.no==s.no&&this.school.equals(s.school);
    }
}
//equals方法重写的时候要彻底
public class equalsSENRU {
    public static void main(String[] args) {
        Address addr=new Address("天津","涞水","888");
        User u1=new User("zhangsan",addr);
        User u2=new User("zhangsan",new Address("天津","涞水","888"));
        System.out.println(u1.equals(u2));//true

        User u3=new User("zhangsan",new Address("北京","大型","555"));
        System.out.println(u1.equals(u3));//false

        User u4=new User("lisi",new Address("天津","涞水","888"));
        System.out.println(u1.equals(u4));//false
    }
}

class User{
    //用户名
    String name;

    //用户的住址
    Address addr;

    public User() {
    }

    public User(String name, Address addr) {
        this.name = name;
        this.addr = addr;
    }

    //重写equals方法
    //当用户的用户名和住址都相同表示同一个用户
    //判断的是User对象和User对象是否相等
    public boolean equals(Object obj){
        //用户名和用户名相同,住址和住址相同后认为是同一个用户
        if(obj==null||!(obj instanceof User)) return false;
        if(this==obj) return true;
        User u=(User) obj;
        if(this.name.equals(u.name)&&this.addr.equals(u.addr)){
            return true;
        }
    return false;
    }

}

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

    //重写toString方法
    //重写equals方法
    public boolean equals(Object obj){
        if(obj==null||!(obj instanceof Address)) return true;
        if(this==obj) return true;
        Address add=(Address) obj;
        //怎么判断家庭住址相同
        //所有的相同
        if(this.city.equals(add.city)&&this.street.equals(add.street)&&this.zipcode.equals(add.zipcode)){
            return true;
        }
        return false;
    }

}

finalize

/**
 *  finalize()方法-------------------(了解就行  了解就行  了解就行)------------------------------
 *      这个方法是protected修饰的,在Object类中这个方法的源代码是?
 *          protected void finalize ()  throws Throwable{}
 *          GC负责调用finalize()方法
 *
 *  1、finalize()方法只有一个方法体,里面没有代码,而且这个方法是protected修饰的
 *
 *  2、这个方法不需要程序员手动调用,JVM的垃圾回收器负责调用这个方法
 *      不像equals和toString,equals和toString方法需要你写代码调用的
 *      finalize()只需要重写,重写玩自动会用程序来调用
 *
 *  3、finalize()方法的执行时机:
 *
 *      当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法
 *
 *  4、finalize()方法实际是Sun公司为java程序员准备的一个时机“垃圾销毁时机”,
 *      如果希望在对象销毁时机执行一段代码的话,这段代码要写字finalize()方法中
 *
 *  5、静态代码块的作用是什么???
 *      static{
 *          ...
 *      }
 *      静态代码块在类加载时刻执行,只执行一次
 *      这是Sun准备的类加载时机
 *
 *      finalize()方法同样也是Sun为程序员准备的一个时机
 *      这个时机是垃圾回收时机
 *
 *  6、提示>>>>>>>>>>>>>>
 *      java中的垃圾回收器不会轻易启动:垃圾太少或者时间没到的种种条件下,垃圾回收器不启动
 *
 *
 *  */
public class finalize {
    public static void main(String[] args) {
       /* Person p=new Person();

        //怎么把Person对象变成垃圾
        p=null;

        */

        //多造垃圾
        for (int i = 0; i < 100; i++) {
            Person p = new Person();
            p=null;
            if(i%50==0){
                System.gc();//建议启动垃圾回收器的语句
            }
        }
    }
}

class Person {
    //重写finalize方法
    //Person对象在背垃圾回收器回收的时候,垃圾回收器负责调用:p.finalize();
    protected void finalize() throws Throwable {
        System.out.println("即将被销毁");
    }
}

hashCode

/**
 * hashCode方法:
 *      在Object中的hashCode是怎样的?
 *           public native int hashCode();
 *           这个方法不是抽象方法,带有native关键字,底层调用的C++
 *
 *       hashCode()方法返回的是哈希码:
 *          实际上就是一个java对象的内存地址经过哈希算法,得到的一个值,所以 hashCode()方法的执行结果等于等同看做一个java对象的内存地址
 */
public class hashCode {
    public static void main(String[] args) {
        Object o=new Object();
        int hashCodeValue1=o.hashCode();
        //对象内存地址是经过哈希算法转换的一个数字,可以看做内存地址
        System.out.println(o.hashCode());//284720968

        MyClass mc=new MyClass();
        int hashCodeValue2=mc.hashCode();
        System.out.println(mc.hashCode());//793589513
    }
}

class MyClass{

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值