重踏学习Java路上_Day11(Object)

1:Eclipse的概述使用(掌握)
    请参照ppt和课堂练习.txt
    
2:API的概述(了解)
    (1)应用程序编程接口。
    (2)就是JDK提供给我们的一些提高编程效率的java类。

3:Object类(掌握)
    (1)Object是类层次结构的根类,所有的类都直接或者间接的继承自Object类。

        API解释:类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
    (2)Object类的构造方法有一个,并且是无参构造
        这其实就是理解当时我们说过,子类构造方法默认访问父类的构造是无参构造,因为所有的类的父亲都是Object,而Object的构造方法只有一个,就是无参构造
    (3)要掌握的方法:
A:toString()
  返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明但易于读懂的信息表达式。建议所有子类都重写此方法。
Object 类的 toString 方法返回一个字符串,该字符串由类名(对象是该类的一个实例)、at 标记符“@”和此对象哈希码的无符号十六进制表示组成。换句话说,该方法返回一个字符串,它的值等于:
getClass().getName() + '@' + Integer.toHexString(hashCode())  ,这个没有什么意义,最好全部子类都重写此方法。   直接输出对象名称:即System.out.println(s);即默认调用执行s.toString()方法。

public String toString()
    A:返回该对象的字符串表示。
        底层源码。
        public static String valueOf(Object obj) {
                    return (obj == null) ? "null" : obj.toString();
            }
    B:它的值等于:
        getClass().getName() + '@' + Integer.toHexString(hashCode())
    C:由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。
        a:手动重写
        b:自动生成


B:equals()
public boolean equals(Object obj)
    A:指示其他某个对象是否与此对象“相等”。
    B:默认情况下比较的是对象的引用是否相同。
    C:由于比较对象的引用没有意义,一般建议重写该方法。
        a:手动重写
        b:自动生成
    D:==和equals()的区别。(面试题)

    比较两个对象是否相同。默认情况下,比较的是地址值是否相同。
而比较地址值是没有意义的,所以,一般子类也会重写该方法。
重写过程,我也详细的讲解和分析了。但是最终还是自动生成。
例子:    @Override
    public boolean equals(Object obj) {
        //因为不能直接用obj进行比较,而且因为我们要使用学生类特有成员变量,所以我们需要向下转型
        Student s = (Student) obj;//向下转型
        if (this.name.equals(s.name) && this.age == s.age) {
            return true;
        } else {
            return false;
        }

    }

==:
基本类型:比较的就是值是否相同
引用类型:比较的就是地址值是否相同
equals:
引用类型:默认情况下,比较的是地址值。
不过,我们可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同
为了程序的健壮性,改进版:
@Override
    public boolean equals(Object obj) {
        //为了提高效率
        if(this == obj){
            return true;
        }
        
        //为了提供程序的健壮性
        //我先判断一下,obj是不是学生的一个对象,如果是,再做向下转型,如果不是,直接返回false。
        //这个时候,我们要判断的是对象是否是某个类的对象?
        //记住一个格式:对象名 instanceof 类名   
        //instanceof关键字用来确定对象所属的类。
        //表示:判断该对象名是否是该类名一个对象
        if(!(obj instanceof Student)){
            return false;
        }
        //如果是就继续
        
        Student s = (Student)obj;
        //System.out.println("同一个对象,还需要向下转型并比较吗?");
        return this.name.equals(s.name) && this.age == s.age;
    }
但其实一般我们都是用重写的,ide自动生成版较多
@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;
    } 

(4)要了解的方法:
     A:hashCode() 返回对象的哈希值。由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。(这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)这个值与地址值有关,但不是实际地址值,所以可以理解为地址值。

    public int hashCode()
    1:返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。
    2:不同对象的,hashCode()一般来说不会相同。
      但是,同一个对象的hashCode()值肯定相同。
    3:不是对象的实际地址值,可以理解为逻辑地址值。
        举例:物体和编号。  

 
    B:getClass() 返回对象的字节码文件对象,反射中我们会详细讲解    

    public final Class getClass()   Class可以理解为jvm读取.class文件(字节码文件)后生成在内存区保存的类
        A:返回此 Object 的运行时类。
        B:可以通过Class类中的一个方法,获取对象的真实类的全名称。    
              public String getName()


    C:finalize() 用于垃圾回收,在不确定的时间

    protected void finalize()
      A:当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。
      B:垃圾回收器不会马上回收垃圾,但是我们可以建议它尽快回收垃圾。(System.gc()方法)
      C:主要针对堆内存。

                 D:对于任何给定对象,Java 虚拟机最多只调用一次 finalize 方法。


    D:clone() 可以实现对象的克隆,包括成员变量的数据复制,但是它和两个引用指向同一个对象是有区别的。

创建并返回此对象的一个副本,这种克隆机制十分高效,而且二者之间完全隔离。
自定义类实现克隆步骤:
A:自定义类实现Cloneable接口,这是一个标记性接口,实现这个接口的类的对象可以实现自我克隆。
B:自定义类中重写Object类的clone()方法。
C:重写clone()方法时通过super.clone()调用Object类的clone()方法来得到该对象的副本,并返回该副本。
注意:
A:克隆和两个引用指向同一个对象的区别?
B:Object类clone()方法虽然简单,易用,但仅仅是一种”浅克隆”,它只克隆该对象所有的Field值,不会
对引用类型的Field所引用的对象进行克隆。开发中,我们也可以实现对象的”深度克隆”。

protected Object clone():创建并返回此对象的一个副本。
A:重写该方法
Cloneable:此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。
这个接口是标记接口,告诉我们实现该接口的类就可以实现对象的复制了。
      记住哦,要想把具体类打开其复制的权限,记住在具体类的名字旁边实现Cloneable 接口,虽然只是空接口,但他是标记接口,告诉jvm这个具体类可以进行克隆操作,我曾经把接口实现到测试类上,结果怎么找都发现不了哪里错了,记住啊,要把接口实现于具体类上

例子:具体类截取代码:
public class Student implements Cloneable

    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
    
测试类:
public class StudentDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        //创建学生对象
        Student s = new Student();
        s.setName("林青霞");
        s.setAge(27);
        
        //克隆学生对象
        Object obj = s.clone();
        Student s2 = (Student)obj;
        System.out.println("---------");
        
        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());
        System.out.println(s2.getName()+"---"+s2.getAge());
        System.out.println(s3.getName()+"---"+s3.getAge());
        
    }
}
    

(5)两个注意问题;
        A:直接输出一个对象名称,其实默认调用了该对象的toString()方法。例子:System.out.println(s);
        B:面试题
            ==和equals()的区别?
            A:==
                基本类型:比较的是值是否相同
                引用类型:比较的是地址值是否相同
            B:equals()
                只能比较引用类型。默认情况下,比较的是地址值是否相同。
                但是,我们可以根据自己的需要重写该方法。

原文地址:https://www.cnblogs.com/canceler/p/4606633.html