美文网首页
进阶:Object类

进阶:Object类

作者: 雪上霜 | 来源:发表于2020-04-27 15:07 被阅读0次
  • Object类的如何查看:

    • 去源代码中查看
    • 去查阅Java的类库的帮助文档。
  • API:应用程序编程接口

    • 整个JDK类库就是一个就是一个javase的API。
    • 每个API都会配置一套API帮助文档。
    • SUN公司提前写好的这套类库就是API。
      • protected Object clone() //负责对象克隆的。
      • int hashCode() //获取对象哈希值的一个方法。
      • boolean equals(Object obj) //判断两个对象是否相等
      • String toString() //将对象转换成字符串形式
      • protected void finalize() //垃圾回收器负责调用的方法
  • toString 设计目的:可以调用这个方法返回对象的字符串形式。

  • 建议都去重写toString方法。是一个简洁的、详实的、易阅读的。

//源代码
public String toString(){
    return this.getClass().getName()+"@"+Integer.toHexString(hashCode());
}
public class Test{
    public static void main(String[] args){
        MyTime m = new MyTime();
        m.toString();
        System.out.println(m);
        System.out.println(m.toString());
    }
}

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 String toString(){
        System.out.println(this.year+"年"+this.month+"月"+this.day+"日");
    }
}
  • equals判断两个对象是否相等的。
  • 判断两个java对象不能用==,这样比较的是引用的值。要判断两个对象相等,equals不够用,需要重写。
//源代码
public boolean equals(Object obj){
    return (this==obj);
}
public class Test{
    public static void main(String[] args){
        int a = 100;
        int b = 100;
        System.out.println(a==b);
        
        MyTime t1 = new MyTime(2008,8,8);
        MyTime t2 = new MyTime(2008,8,8);
        System.out.println(t1 == t2);//比较的是t1和t2中的值。

        boolean b = t1.equals(t2);
    }
}


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 t = (MyTime)obj;
            if(t.year == this.year && t.month == this.month && t.day == this.day){
            return true;
            }
        }
        return false;
    }
}
  • 上例可以运行,但效率低,有bug
public class Test{
    public static void main(String[] args){
        int a = 100;
        int b = 100;
        System.out.println(a==b);
        
        MyTime t1 = new MyTime(2008,8,8);
        MyTime t2 = new MyTime(2008,8,8);
        System.out.println(t1 == t2);//比较的是t1和t2中的值。

        boolean b = t1.equals(t2);
    }
}


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 == null){
            return false;
        }
        if(!(obj instanceof MyTime)){
            return false;
        }
        if(this == obj){
            return true;
        }
        MyTime t = (MyTime)obj;
        if(t.year == this.year && t.month == this.month && t.day == this.day){
            return true;
            }
        return false;
    }
    
    /*
    public boolean equals(Object obj){
        if(obj == null){
            return false;
        }
        if(!(obj instanceof MyTime)){
            return false;
        }
        if(this == obj){
            return true;
        }
        MyTime t = (MyTime)obj;
        return t.year == this.year && t.month == this.month && t.day == this.day;
    }
    */
}
//大部分下这样写
String s = "hello worl";
//其实String也是一个类,不属于基本数据类型,既然String是一个类,那么一定存在构造方法。
String s3 = new String("hello worl");
//比较两个字符串不能使用==。必须使用equals方法。
//String已经重写了toString方法。
  • java中基本数据类型比较使用==,引用类型使用equals方法。

  • public class Test{
      public static void main(String[] args){
          Student s1 = new Student(111,"sjogn");
          Student s2 = new Student(222,"hfosnf");
          
          System.out.println(s1 == s2);
          System.out.println(s1.equals(s2));
          
          Student s11 = new Student(111,new String("sjogn"));
          Student s21 = new Student(222,new String("hfosnf"));
          
          System.out.println(s11 == s21);
          System.out.println(s11.equals(s21));
      }
    }
    
    class Student{
      int no;
      String school;
      
      public Student(){
      
      }
      public Student(int no,String school){
          this.no = no;
          this.school = school;
      }
      
      public String toString(){
          return "学号" + no + ",所在学校名称" + school;
      }
      
      public boolean equals(Object obj){
          if(obj == null || !(obj instanceof Student))
              return false;
          if(this == obj)
              return true;
          Student s = (Student)obj;
          return s.no == this.no && this.school.equals(s.school);
          return false;
      }
    }
    
  • 所以类的toString方法是需要重写的。

  • 以后所有类的equals方法也需要重写。

public class Test{
    public staic void main(String[] args){
        Address addr = ;
        User u1 = new User("张三",new Address("北京","大兴区","1111"));
        User u2 = new User("张三",new Address("北京","大兴区","1111"));
        
    }
}

class User{
    String name;
    Address addr;
    
    public User(){
    
    }
    public User(String name,Address addr){
        this.name = name;
        this.addr = addr;
    }
    
    public boolean equals(Object obj){
        if(obj == null || !(obj instanceof User))
            return false;
        if(obj == this)
            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;
    }
    
    public boolean equals(Object obj){
        if(obj == null || !(obj instanceof User))
            return false;
        if(obj == this)
            return true;
        User u = (User)obj;
        if(this.city.equals(u.city) && this.street.equals(u.street) && this.zipcode.equals(u.zipcode)){
            return true;
        }
        return false;
    }
}
  • finalize方法

  • //源码
    protected void finalize() throws Throwable{}
    
  • finalize方法只是一个方法体,没有代码,这个方法是protected的。

  • finalize方法的执行时机:当一个Java对象即将被垃圾回收的时候,垃圾回收器负责调用finalize方法。不像equals、toString需要写代码调用,finalize方法只需重写,GC回收器负责调用。

  • finalize方法实际上是SUN公司为Java程序员准备的一个时机,垃圾销毁时机,如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize方法中。

  • 静态代码块的作用:static{....}静态代码块在类加载时刻执行,并且只执行一次,这是一个SUN准备的类加载时机。

  • finalize方法同样也是SUN为程序员准备的一个时机,这个时机是垃圾回收时机。

  • java中垃圾回收器不是轻易启动的,垃圾太少,或时间没到,种种条件下,有可能启动,可能不启动。

  • public class Test{
      Person p = new Person();
      
      //怎么让Person对象变成垃圾。
      p = null;
      
      //制造垃圾。
      for(int i = 0;i < 100000000;i++){
          Person p = new Person();
          p = null;
      }
      
      //建议启动垃圾回收机制
      System.gc();
    }
    
    //项目业务需求:所有对象在JVM中被释放的时候,请记录一下释放时间,记录对象被释放的时间点,这个负责记录的代码写到哪里?
    //写到finalize()中。
    class Person{
      //Person类型对象被垃圾回收器回收的时候,垃圾回收器负责调用:p.finalize()
      protected void finalize() throw Throwable{
          System.out.println("即将被销毁");
      }
    } 
    
  • 自从jdk9就不使用了。

  • protected Object clone() //不讲

  • hashCode方法。

    • public native int hashCode();
    • 这个方法不是抽象方法,底层调用C++程序,hashCode方法返回的是哈希码。
    • 实际上是Java对象的内存地址,经过哈希算法得到的一个值,所以hashCode()方法的执行结果可以等同看作一个Java对象的内存地址。
  • public class Test{
      public static void main(String[] args){
          Object o = new Object();
          int hashCodeValue = o.hashCode();
          
          System.out.println(hashCodeValue);
          
          MyClass mc = new MyClass();
          int hashCodeValue2 = mo.hashCode();
          System.out.println(hashCodeValue2);
          
          MyClass mc2 = new MyClass();
          System.out.println(mo2.hashCode());
      }
    }
    
    class MyClass{
    
    }
    

相关文章

网友评论

      本文标题:进阶:Object类

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