• JavaSE学习----(七)JDK类库的根类:Object



    在这里插入图片描述

    一.Object类

    1.学习预备知识

    • Object这个老祖宗类中的方法我们需要研究一下,因为这些方法都是所有子类通用的,任何一个类都默认继承Object类

    • Object类中有哪些常用的方法?

      • 我们去哪里找这些方法?
        第一种:去源代码当中(但是这种方法比较麻烦,源代码也比较难)
        第二种:去查阅java类库的帮助文档
      • 什么是API?
        应用程序编程接口(Application Program Interface)
        整个JDK的类库就是一个JavaSE的API
        每一个API都会配置一套API帮助文档
        SUN公司提前写好的这套类库就是API(一般一份API对应一份API帮助文档)
      • 目前我们需要知道哪几个方法?
        (1)protected Object clone() //负责对象克隆的
        (2)int hashCode() //获取对象哈希值的一个方法
        (3)boolean equals(Object obj) //判断两个对象是否相等
        (4)String toString() //将对象转换为字符串的形式
        (5)protected void finaliaze() //垃圾回收器负责调用的方法

    2.关于Object类中的toString()方法

    • (1)源代码
      在这里插入图片描述
    • (2)源代码上toString()方法的默认实现是:类名@对象的内存地址转换为十六进制的形式
    • (3)SUN公司设计toSrting()方法的目的是什么?
      通过调用这和方法可以将一个“java对象”转换成“字符串”
    • (4)其实SUN公司开发java语言的时候,建议所有的子类都去重写toString()方法,toString()方法应该是一个简洁的,详实的,易阅读的。

    3.关于Object类中的equals()方法

    • (1)源代码
      在这里插入图片描述
    • (2)SUN公司设计equals方法的目的是什么?
      以后编程的过程中,都要通过equals方法来判断两个对象是否相等,equals方法是判断两个对象是否相等的。
    • (3)我们需要研究一下Object类给的这个默认的equals方法够不够用
      在Object类中的equals方法当中默认采用的是"= ="判断两个对象是否相等,而  "= ="判断的是两个java对象的内存地址,我们应该判断两个java对象的内容是否相等,所以equals方法不够用,需要子类重写equals。
    • (4)判断两个java对象是否相等,不能使用"= =",因为"= ="比较的是两个对象的内存地址。
    //判断两个基本数据类型的数据是否相等直接使用"=="就行
    int a = 100;
    int b = 100;
    //这个"=="是判断a中保存的100和b中保存的100是否相等
    System.out.println(a == b);//ture(相等) false(不相等)
    
    
    //创建两个java对象是否相等,我们怎么做?能直接使用"=="吗?
    //创建一个日期对象是:2022年9月11日
    Mytime t1 = new Mytime(2022,9,11);//假设Mytime t1的内存地址为0x1234
    //创建一个新的日期对象,但表示的日期也是:2022年9月11日
    Mytime t2 = new Mytime(2022,9,11);//而t2 的内存地址为0x2345
    
    //测试一下,比较两个对象是否相等,能不能使用"=="
    //这里的"=="判断的是:t1保存的对象内存地址和t2中保存的内存地址是否相等
    System.out.println(t1 == t2);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    在这里插入图片描述
    在这里插入图片描述

    • (5)怎么重写?
    package com.bjpowernode.java.csdntest;
    
    import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
    
    public class csdntest02 {
        public static void main(String[] args) {
                MyTime m1 = new MyTime(2022,9,11);
                MyTime m2 = new MyTime(2022,9,11);
                boolean flag = m1.equals(m2);
                      System.out.println(flag);
    
        }
    }
    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) {
                        int year1 = this.year;
                        int month1 = this.month;
                        int day1 = this.day;
    
    
                        if (obj instanceof  MyTime){
                            MyTime mt  = (MyTime)obj;
                            int year2 = this.year;
                            int month2 = this.month;
                            int day2 = this.day;
                            if (year1==year2&&month1==month2&&day1==day2){
                                return  true;
                            }
                        }
    
                             return false;
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    在这里插入图片描述

    • ***上述equals方法有些冗余,怎么改进呢?***
    //改良equals方法
     public boolean equals(Object obj) {
     //如果obj是空,直接返回false
                       if (obj == null){
                           return false;
                       }
                        if (!(obj instanceof MyTime)){
                        //如果obj不是一个MyTime,没必要比较了,直接返回false
                            return  false;
                        }
                        if (this == obj){
                        //如果this和obj保存的呢村地址相同,没必要比较了,直接返回true
                        //内存地址相同的时候指向的堆内存的对象肯定是同一个
                            return  true;
                        }
                        //程序能够执行到此处说明什么?
                        //说明obj不是null,obj是MyTime类型
                        //
                        MyTime t = (MyTime)obj;
                        if (this.year==t.year&&this.month==t.month&&this.day==t.day){
                            return  true;
                        }
                        //程序能执行到这里直接返回false
                             return false;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    • 总结:toString方法
      以后所有类的toString方法是需要重写的。重写规则:越简单越明了越好
      System.out,println(引用);这里会自动调用“引用”的toString方法。String类是sun公司写的,toString方法已经重写了。
    • equals方法
      以后所有类的equals方法也需要重写,因为Object中的equals方法比较的是两个对象的内存地址,我们应该比较内容,所以要重写。重写规则:自己定,主要是看什么和什么相等时表示两个对象相等。
      基本数据类型比较实用: ==

      对象和对象比较:调用equals方法
      String类是sun公司写的,所以String类的equals方法重写了。以后判断两个字符串是否相等,最好不要用==,要调用equals方法。

    4.关于Object类中的finalize()方法

    注意:这个方法在JDK9开始过时了

    • (1)这个方法是protected修饰的,只有一个方法体,里面没代码。
    • (2)在Object类中的源代码:
      在这里插入图片描述
    • (3)这个方法不需要程序员手动调用,JVM的垃圾回收机制负责调用这个方法
    • (4)finalize()方法的执行时机
      当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。
    • (5)finalize()方法实际上是sun公司为java程序员准备的一个时机,垃圾销毁时机。如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法中。
    • (6)静态代码块的作用是什么?
      static{

      }
      静态代码块在类加载时刻执行,并且只执行一次,这是一个sun准备的类加载时机。

    我们可以写一下这个时机

    public class Test{
    		public static void main(String[] args){
    			person p = new person();
    			p = null;
    
    	}
    }
    class Person{
    	protected void finalize() throws Throwable{
    System.out.println("即将被销毁")}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    注意:项目开发中可能有这样的要求:所有对象在JVM中被释放的时候,请记录一下施放时间,记录对象被释放的时间点,这个负责记录的代码写在哪里?写在finalize()方法中。

    • (7)提示:
      java中的垃圾回收器不是轻易启动的,垃圾太少,或者四件没到种种情况下,有可能启动也有可能不启动。

    5.关于Object类中的hashcode方法

    • 在Object中的hashCode()方法是怎样的:
      public native int hashCode();
      这个方法不是抽象方法,带有native关键字,底层调用c++程序。
    • hashCode()返回的是哈希码
      实际上就是一个java对象的内存地址,经过哈希算法,得出的一个值,所以hashCode()方法的执行结果可以等同看作一个java对象的内存地址。
      在这里插入图片描述

    二.内部类

    1.什么是内部类?

    内部类:在类的内部又定义了一个新的类,被称为内部类。

    2.内部类的分类

    • 静态内部类:类似于静态变量
    • 实例内部类:类似于实例变量
    • 局部内部类:类似于局部变量

    3.举例

    使用内部类编写的代码,可读性很差,能不用尽量不用
    在这里插入图片描述

    4.匿名内部类

    • 匿名内部类是局部内部类的一种,因为这个类没有名字而得名,叫做匿名内部类。
      在这里插入图片描述
      这个表面看上去好像是接口可以直接new了,实际上并不是接口可以new,后面的{ }代表了对接口的实现。

    • 为什么不建议使用匿名内部类?
      因为一个类没有名字,没有办法重复使用,另外代码太乱,可读性太差。

    5.为什么要学习匿名内部类?

    学习匿名内部类是为了让大家以后阅读别人的代码的时候能够理解,并不代表以后都要这样写,因为匿名内部类有两个缺点:
    ——缺点一:太复杂,太乱,可读性差。
    ——缺点二:类没有名字,以后想重复使用,不能用。

    在这里插入图片描述
    在这里插入图片描述

    在这里插入图片描述

  • 相关阅读:
    11c++呵呵老师【TSubobclass生成物体】
    VUE v-for 循环的 2 个使用
    tensorflow2 -------------LeNet--------------
    【Android】-- 按钮(复选框CheckBox、开关按钮Switch、单选按钮RadioButton)
    FTP主动模式和被动模式(2)- 防火墙对FTP的影响 ASPF
    【JVM】 类加载器 ClassLoader
    pytorch中torch.mul、torch.mm、torch.matmul的区别
    python 二叉树,先序回溯,层序队列,队列基础用法
    webpack5零基础入门-5使用webpack处理stylus文件
    linux 命令大全
  • 原文地址:https://blog.csdn.net/qq_61899969/article/details/126806499