美文网首页
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中的方法

    1,String toString() 将对象转换成字符串方法 源代码 public String toSt...

  • JavaSE进阶十 线程二

    死锁 什么是死锁 死锁是指两个或两个以上的线程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞的现象,若...

  • js 创建对象

    创建对象的几种方法 方法一:new Object() 方法二:{} 方法三:function xx() 为对象中添...

  • Object类中常见的方法

    一.Object类中的toString()方法 object 默认方法 toString方法,toString()...

  • 收藏整理

    Object-C 进阶 深入理解iOS开发中的BitCode功能 iOS面试题:腾讯二面以及参考思路 <精华篇>:...

  • Object中的方法

    曾经被问过,Object中的方法。当时没有回答好。 public final native Class ge...

  • 第9条:覆盖equals时总要覆盖hashCode

    equals方法和hashCode方法均是Object对象的方法。Object中关于hashCode约定的规范如下...

  • 原型式继承:object.create()

    Object.create()方法的第二个参数与Object.defineProperties()方法的第二个参数...

  • sleep()和wait()方法的区别

    一、sleep()方法是属于线程类Thread中的一个方法,而wait()方法属于Object。 二、 sleep...

  • JavaSE进阶九 IO流二

    File类 File类和四大家族没有关系,所以File类不能完成文件的读和写。 File对象代表什么?文件和目录路...

网友评论

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

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