zoukankan      html  css  js  c++  java
  • JavaSE学习笔记(十一)—— 常用API之Object类

      Object 是类层次结构的根类。每个类都使用 Object 作为超类。 每个类都直接或者间接的继承自Object类。

      Object类的构造方法有一个,并且是无参构造。这其实就是理解当时我们说的,子类构造方法默认访问父类的构造是无参构造。

    一、hashCode()

      public int hashCode():返回该对象的哈希码值。

      注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值。你可以理解为地址值。

    Student s1 = new Student();
    System.out.println(s1.hashCode()); // 11299397
    Student s2 = new Student();
    System.out.println(s2.hashCode());// 24446859
    Student s3 = s1;
    System.out.println(s3.hashCode()); // 11299397

    二、getClass()

      public final Class getClass():返回对象的字节码文件对象

      其中返回值Class类有一个方法public String getName():以 String 的形式返回此 Class 对象所表示的实体

    Student s = new Student();
    Class c = s.getClass();
    String str = c.getName();
    System.out.println(str); // cn.itcast_01.Student
    
    //链式编程
    String str2  = s.getClass().getName();
    System.out.println(str2);

    三、toString()

      public String toString():返回该对象的字符串表示。

      默认是由类的全路径+'@'+哈希值的十六进制表示。这个表示其实是没有意义的,一般子类都会重写该方法。

      怎么重写呢? 把该类的所有成员变量值组成返回即可。但是最终还是自动生成。

    public class Student {
        private String name;
        private int age;
    
        public Student() {
            super();
        }
    
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        get/set...
    
        @Override
        //重写toString()方法
        public String toString() {
            return "Student [name=" + name + ", age=" + age + "]";
        }
    
        // @Override
        // public String toString() {
        // // return super.toString();
        // // return "hello";
        // return "姓名:" + name + ",年龄:" + age;
        // }
    }
    public class StudentDemo {
        public static void main(String[] args) {
            Student s = new Student();
            System.out.println(s.hashCode());
            System.out.println(s.getClass().getName());
            System.out.println("--------------------");
            System.out.println(s.toString());// 没重写toString()之前:cn.itcast_02.Student@42552c
            System.out.println("--------------------");
            // toString()方法的值等价于它
            // getClass().getName() + '@' + Integer.toHexString(hashCode())
            // this.getClass().getName()+'@'+Integer.toHexString(this.hashCode())
    
            // cn.itcast_02.Student@42552c
            System.out.println(s.getClass().getName() + '@'
                    + Integer.toHexString(s.hashCode()));
    
            System.out.println(s.toString());
    
            // 直接输出对象的名称
            System.out.println(s);
        }
    }

      注意:直接输出一个对象的名称,其实就是调用该对象的toString()方法。

    四、equals()

      public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。 

      这个方法默认情况下比较的是地址值。比较地址值一般来说意义不大,所以我们要重写该方法。

      怎么重写呢?一般都是用来比较对象的成员变量值是否相同。

    public class StudentDemo {
        public static void main(String[] args) {
            Student s1 = new Student("林青霞", 27);
            Student s2 = new Student("林青霞", 27);
            System.out.println(s1 == s2); // false
            Student s3 = s1;
            System.out.println(s1 == s3);// true
            System.out.println("---------------");
    
            System.out.println(s1.equals(s2)); // obj = s2; //false
            System.out.println(s1.equals(s1)); // true
            System.out.println(s1.equals(s3)); // true
            Student s4 = new Student("风清扬",30);
            System.out.println(s1.equals(s4)); //false
            
            Demo d = new Demo();
            System.out.println(s1.equals(d)); //ClassCastException
    
        }
    }
    
    class Demo {}

    【最初版】

    public class Student {
        private String name;
        private int age;
    
        public Student() {
            super();
        }
    
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
        get/set...
        
        @Override
        public boolean equals(Object obj) {
            // return true;
            //这里要改进,根据这里比较的成员变量来决定返回true还是false
            //这里其实要比价的就是name和age
            //但是,name是String类型的,而String是引用类型的,所以,在这里不能直接用==比较,应该用equals()比较
            //String的equals()方法是重写自Object类的,比较的是字符串的内容是否相同
            //this -- s1
            //obj -- s2
            //我们要使用的是学生类的特有成员变量,所以要向下转型
            Student s = (Student)obj; //s -- obj -- s2;
            if(this.name.equals(s.name) && this.age == s.age) {
                return true;
            }else {
                return false;
            }
        }
     
    }

    【优化版】

      重写的代码优化:提高效率,提高程序的健壮性。

    @Override
    public boolean equals(Object obj) {
        //为了提高效率
        if(this == obj){
            return true;
        }
        
        //为了提供程序的健壮性
        //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
        //这个时候,我们要判断的是对象是否是某个类的对象?
        //记住一个格式:对象名 instanceof 类名
        //表示:判断该对象名是否是该类名一个对象
        if(!(obj instanceof Student)){
            return false;
        }
        //如果是就继续
        
        Student s = (Student)obj;
        //System.out.println("同一个对象,还需要向下转型并比较吗?");
        return this.name.equals(s.name) && this.age == s.age;
    }

    【最终版】——自动生成

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Student other = (Student) obj;
        if (age != other.age)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }

    【==和equals的区别】

      ==:

        基本类型:比较的就是值是否相同

        引用类型:比较的就是地址值是否相同

      equals:

        引用类型:默认情况下,比较的是地址值。不过,我们可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同

    五、clone()

      protected Object clone():创建并返回此对象的一个副本。可以实现对象的克隆,包括成员变量的数据复制,但是它和两个引用指向同一个对象是有区别的。

      需要重写该方法:

    public class Student implements Cloneable {
        private String name;
        private int age;
    
        public Student() {
            super();
        }
    
        public Student(String name, int age) {
            super();
            this.name = name;
            this.age = age;
        }
    
      get/set...
        
        @Override
        protected Object clone() throws CloneNotSupportedException {
            return super.clone();
        }
    }

      Cloneable:此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。

      这个接口里面并没有任何方法,是一个标记接口,告诉我们实现该接口的类就可以实现对象的复制了。

    public class StudentDemo {
        public static void main(String[] args) throws CloneNotSupportedException {
            //创建学生对象
            Student s = new Student();
            s.setName("林青霞");
            s.setAge(27);
    
            //克隆学生对象
            //如果Student类没有重写clone()方法,这里将无法调用clone()
            Object obj = s.clone();
            Student s2 = (Student) obj;
    
            System.out.println(s.getName()+"---"+s.getAge());
            System.out.println(s2.getName()+"---"+s2.getAge());
    
            //以前的做法
            Student s3 = s;
            System.out.println(s3.getName()+"---"+s3.getAge());
            System.out.println("---------");
    
            //其实是有区别的
            s3.setName("风清扬");
            s3.setAge(30);
            System.out.println(s.getName()+"---"+s.getAge());//风清扬---30
            System.out.println(s2.getName()+"---"+s2.getAge());//林青霞---27
            System.out.println(s3.getName()+"---"+s3.getAge());//风清扬---30
    
        }
    }

    六、finalize()

      protected void finalize():当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。用于垃圾回收,因为无法确定该方法什么时候被调用,很少使用。    

      Java允许在类中定义一个名为finalize()的方法。它的工作原理是:一旦垃圾回收器准备好释放对象占用的存储空间,将首先调用其finalize()方法。并且在下一次垃圾回收动作发生时,才会真正回收对象占用的内存。

      关于垃圾回收,有三点需要记住:

    1. 对象可能不被垃圾回收。只要程序没有濒临存储空间用完的那一刻,对象占用的空间就总也得不到释放。
    2. 垃圾回收并不等于“析构”。
    3. 垃圾回收只与内存有关。使用垃圾回收的唯一原因是为了回收程序不再使用的内存。

    【finalize()的用途】

      无论对象是如何创建的,垃圾回收器都会负责释放对象占据的所有内存。这就将对finalize()的需求限制到一种特殊情况,即通过某种创建对象方式以外的方式为对象分配了存储空间。不过这种情况一般发生在使用“本地方法”的情况下,本地方法是一种在Java中调用非Java代码的方式。

  • 相关阅读:
    POJ 2723 Get Luffy Out(2-SAT)
    ZOJ 3613 Wormhole Transport
    HDU 4085 Peach Blossom Spring
    NBUT 1221 Intermediary
    NBUT 1223 Friends number
    NBUT 1220 SPY
    NBUT 1218 You are my brother
    PAT 1131. Subway Map (30)
    ZSTU OJ 4273 玩具
    ZSTU OJ 4272 最佳淘汰算法
  • 原文地址:https://www.cnblogs.com/yft-javaNotes/p/10838775.html
Copyright © 2011-2022 走看看