美文网首页
JavaSE进阶二 Object中的方法

JavaSE进阶二 Object中的方法

作者: SimonLike | 来源:发表于2021-06-09 10:09 被阅读0次

    1,String toString() 将对象转换成字符串方法

    • 源代码

         public String toString() {
            return this.getClass().getName() + "@" + Integer.toHexString(hashCode());
        }
      
      • 源码上toString()方法默认实现:类名@对象的内存地址转换为十六进制的形式
    • toString()方法的作用是什么?

      • toString()方法的设计目的是:通过调用这个方法可以将一个"java对象"转换成"字符串表现形式"。
    • 其实SUM公司开发java语言的时候,建议所以的子类都去重写toString()方法。 toString()方法是一个简洁的、详实的、易阅读的。

    • System.out.println(引用);// 这里会自动调用"引用"的toString方法。

    代码示例
    public class Test01 {
        public static void main(String[] args) {
            MyTime t = new MyTime(1970,1,1);
            String s = t.toString();
            //MyTime类重写toString()之前
            System.out.println(s);//  MyTime@23fc625e
    
            //MyTime类重写toString()之后
            System.out.println(s);//  1970年1月1日
        }
    
    }
    
    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;
        }
        // 重写Object中的toString()方法
        public String toString(){
            return this.year + "年" + this.month + "月" + this.day + "日" ;
        }
    }
    

    2,boolean equals(Object obj) 判断两个对象是否相等方法

    • equals方法的源代码

        public boolean equals(Object obj) {
             return (this == obj);
        }
      
      • 以上这个方法是Object类的默认实现。
    • equals方法是判断两个对象是否相等的。

    • 在Object类中的equals方法,默认采用的是"=="符号判断两个java对象是否相等,而"=="判断的是两个java对象的内存地址,我们应该判断两个java对象的内容是否相同。所以Object类中的equals方法不够用,需要子类重新equals方法。

    • 判断两个对象是否相等不能使用"==",因为"=="比较的是两个对象的内存地址。

    代码示例
    public class Test02 {
        public static void main(String[] args) {
            //判断两个基本数据类型的数据是否相等直接使用"=="符号就可以
            int a = 100;
            int b = 100;
            System.out.println(a == b);// true 相等  false 不相等
    
            MyTimes t1 = new MyTimes(2020,2,12);
            MyTimes t2 = new MyTimes(2020,2,12);
    
            // 使用"=="符号判断两个对象(引用)是否相等
            // 结果:t1中保存的对象内存地址和t1中保存的对象内存地址 是不一样的。
            System.out.println(t1 == t2);// false
    
            // 重新equals方法之前
            System.out.println(t1.equals(t2));// false
    
            // 重新equals方法之后
            System.out.println(t1.equals(t2));// true
    
            // 新创建一个日期
            MyTimes t4 = new MyTimes(2020,2,13);
            System.out.println(t1.equals(t4));// false 两个日期不相等
    
        }
    }
    
    class MyTimes{
        int year;
        int month;
        int day;
    
        public MyTimes() {
        }
    
        public MyTimes(int year, int month, int day) {
            this.year = year;
            this.month = month;
            this.day = day;
        }
    
        // 重写Object中的equals()方法
    
        // idea工具生存重写equals
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof MyTimes)) return false;
            MyTimes myTimes = (MyTimes) o;
            return year == myTimes.year && month == myTimes.month && day == myTimes.day;
        }
    
    //  下面是自己练习重写equals()方法 建议新学者动动手,自己写一下
    
    //    public boolean equals(Object obj) {
    //
    //        /*
    //        //步骤写法
    //        // 如果obj是空直接返回false
    //        if (obj == null){
    //            return false;
    //        }
    //        // 如果obj不是MyTimes 直接返回false
    //        if (!(obj instanceof MyTimes)){
    //            return false;
    //        }
    //        // 如果this和obj保存内存地址相同, 直接返回true
    //        if (this == obj){
    //            return true;
    //        }
    //
    //        //程序执行到这里说明 obj不是null 、 是MyTimes类型
    //        MyTimes t3 = (MyTimes) obj;
    //
    //        if (this.year == t3.year && this.month == t3.month && this.day == t3.day){
    //            return true;
    //        }
    //        // 程序能够执行到此处返回false。
    //        return false;
    //    }*/
    //
    //        //改良写法 简版写法
    //        if (obj == null || !(obj instanceof MyTimes) ){
    //            return false;
    //        }
    //
    //        // 如果this和obj保存内存地址相同, 直接返回true
    //        if (this == obj){
    //            return true;
    //        }
    //
    //        //程序执行到这里说明 obj不是null 、 是MyTimes类型
    //        MyTimes t3 = (MyTimes) obj;
    //        return this.year == t3.year && this.month == t3.month && this.day == t3.day;
    //    }
    }
    
    关于使用toString和equals demo代码示例:
    public class Test04 {
        public static void main(String[] args) {
            Student s = new Student(1234,"南京大学");
            Student s2 = new Student(1234,"南京大学");
    
            // toString   s是引用
            System.out.println(s);// 这里会自动调用"引用"的toString方法  输出: Student{no=1234, school='南京大学'}
            System.out.println(s.toString());// Student{no=1234, school='南京大学'}
    
            // equals
            System.out.println(s.equals(s2));//true
    
        }
    }
    class Student{
        int no; //学号
        String school; // 所在学校
    
        public Student() {
        }
    
        public Student(int no, String school) {
            this.no = no;
            this.school = school;
        }
    
        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Student)) return false;
            Student student = (Student) o;
            // 下面注释区是idea编译器重写的return
            // return no == student.no && Objects.equals(school, student.school);
            // 如果不理解使用下面这个return也是可以的
            return no == student.no && school.equals(student.school);
        }
    
        @Override
        public String toString() {
            return "Student{" +
                    "no=" + no +
                    ", school='" + school + '\'' +
                    '}';
        }
    }
    

    3,String类中的toString方法和equals方法

    • String类已经重写了equals方法,比较两个字符串不能使用==,必须使用equals方法;equals是通用的。
    • String类已经重写了toString方法。
    • 结论:(规矩)
      • java中基本数据类型比较是否相等,使用"=="。
      • java中所有的引用数据类型统一使用equals方法来判断是否相等。
    代码示例
    public class Test03 {
        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两次,两个对象内存地址;s3和s4保存的内存地址不同
            // 使用==判断的是内存地址,不是内容。
            System.out.println(s3 == s4);// false
    
            // 比较两个字符串不能使用"==",要使用equals
            // String类已经重写了equals方法
            System.out.println(s3.equals(s4));// true
    
            String x = new String("我好帅!");
            //如果String没有重写toString方法,输出结果:java.lang.String@十六进制的地址
            //经过下面测试发现:String类已经重写了toString方法
            System.out.println(x.toString());//我好帅!
            System.out.println(x);//我好帅!
        }
    }
    
    4,protected Object clone() 克隆对象方法(自行了解一下)

    5,int hashCode() 获取对象哈希值方法

    • 在Object类中的源代码:

    •   public native int hashCode();
      
      • 这个方法不是抽象方法,带有native关键字,底层调用C++程序。
    • hashCode()方法返回的是哈希码:

    •  实际上就是一个java对象的内存地址,经过哈希算法,得出一个值。所以hashCode()方法执行结果可以看做一个java对象的内存地址。
      
    代码示例
    public class Test06 {
        public static void main(String[] args) {
            Object o = new Object();
            //对象内存地址经过哈希算法转换的一个数字,可以等同看做内存地址。
            System.out.println(o.hashCode());//258952499
        }
    }
    

    6,protected void finalize() 垃圾回收器负责调用的方法

    • 在Object类中的源代码:
    •  protected void finalize() throws Throwable { }
      
    • finalize()方法只有一个方法体,里面没有代码,这个方法是protected修饰的。
    • 这个方法不需要程序员收到调用,JVM垃圾回收器负责调用这个方法。
    • finalize()执行的时机:
    •  当一个java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()方法。
      
    • finalize()方法实际上是SUM公司为java程序员准备的一个时机,垃圾销毁时机。
    • 如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法中。
    • java中的垃圾回收器不是轻易启动的,垃圾太少、时间没到等条件下,有可能不启动。
    代码示例
    public class Test05 {
        public static void main(String[] args) {
    
            Person p = new Person();
            // 把Person对象变成垃圾
            // 一个垃圾未启动垃圾回收器
            p = null;
    
    //        // 多制造点垃圾
    //        for (int i = 0; i<1000000; i++){
    //            Person p1 = new Person();
    //            // 把Person对象变成垃圾
    //            p1 = null;
    //        }
    
            // 有一段代码可以建议垃圾回收器启动。
            for (int i = 0; i<1000; i++){
                Person p1 = new Person();
                // 把Person对象变成垃圾
                p1 = null;
                System.gc();// 只是建议启动垃圾回收器,也可能不启动;只是提高了启动垃圾回收器的概率
            }
    
        }
    }
    class Person{
    
        //重写finalize()方法
        // 记录对象被释放的时间点可以写到finalize()方法中
        @Override
        protected void finalize() throws Throwable {
            super.finalize();
            System.out.println(this + " 即将进入销毁");
        }
    }
    

    上篇:JavaSE进阶一 接口
    下篇:JavaSE进阶三 数组

    相关文章

      网友评论

          本文标题:JavaSE进阶二 Object中的方法

          本文链接:https://www.haomeiwen.com/subject/ltgqsltx.html