JavaSE Object(类): hashCode getClass() toString() equals(Object obj)

day11目录:

Object(类)
	public int hashCode()
	public final Class getClass()
	public String toString()
	public boolean equals(Object obj)

11.17_常见对象(API概述以及Object类的概述)(掌握)

A:API(Application Programming Interface) 
	应用程序编程接口
B:Java API
	就是Java提供给我们使用的类,这些类将底层的实现封装了起来,
	我们不需要关心这些类是如何实现的,只需要学习这些类如何使用。
C:Object类概述
	类层次结构的根类
	所有类都直接或者间接的继承自该类
D:构造方法
	public Object()
	回想面向对象中为什么说:
	子类的构造方法默认访问的是父类的无参构造方法

11.18_常见对象(Object类的hashCode()方法)(掌握)

A:案例演示
	public int hashCode()
		a:返回该对象的哈希码值。默认情况下,该方法会根据对象的地址来计算。
		b:不同对象的,hashCode()一般来说不会相同。
	  	   但是,同一个对象的hashCode()值肯定相同。
		c:不是对象的实际地址值,可以理解为逻辑地址值。	
public class MyTest {
    public static void main(String[] args) {
        //java.lang 包下的类 不需要导入包
        // public class Object类 Object 是类层次结构的根类。每个类都使用 Object 作为超类。所有对象(包括数组)都实现这个类的方法。
        //Object 类,是所有类的顶层父类,所有类都是直接或间接继承自她
        //创建对象
        Object obj = new Object();
        System.out.println(obj);
        int i = obj.hashCode();
        System.out.println(i);

        Object obj2 = new Object();
        System.out.println(obj2);
        int i1 = obj2.hashCode();
        System.out.println(i1);

    }
}

· 学习到后面,会和“集合”的知识有关

11.19_常见对象(Object类的getClass()方法)(掌握)

A:案例演示
	public final Class getClass()
		a:返回此 Object 的运行时类。
		b:可以通过Class类中的一个方法,获取对象的真实类的全名称。	
		public String getName()
public class MyTest2 {
    public static void main(String[] args) {
        Object object = new Object();
        System.out.println(object);
        //返回该类的字节码文件对象。Object.java--->Object.class---->加载进内存--->JVM会为Object.class创建对象---->通过getClass()获取字节码文件对象
        //Class 这个类型,用来表示是 字节码文件类型
        Class<?> aClass = object.getClass();

        Object object2 = new Object();
        System.out.println(object2);
        Class<?> aClass1 = object2.getClass();

        System.out.println(object==object2);//false

        System.out.println(aClass==aClass1); //true 字节码文件是一份
    }
}

· 学习到后面,会和“反射”的知识有关

11.20_常见对象(Object类的toString()方法)(掌握)

A:案例演示
	public String toString()
	a:返回该对象的字符串表示。
		源代码:
		 	public String toString() {
   					 return getClass().getName() + "@" + Integer.toHexString(hashCode());
				}
	b:它的值等于: 
		getClass().getName() + '@' + Integer.toHexString(hashCode()) 
	c:由于默认情况下的数据对我们来说没有意义,一般建议重写该方法。
	  怎么重写, 一般是将该类的所有的成员变量组成返回即可
B:最终版
	自动生成
C: 直接输出对应的名称,就是调用对象的toString()方法
public class MyTest {
    public static void main(String[] args) {
        Object obj = new Object();
        //toString();获取该对象的地址值,以字符串的形式返回。
        String s = obj.toString();
        System.out.println(s);
        System.out.println(obj); //当你打印对象名的时候,默认这个对象就在调用toString()方法
        System.out.println(obj.toString());

    }
}

在这里插入图片描述

public class MyTest2 {
    public static void main(String[] args) {
        Student student = new Student();
        student.setName("张三");
        student.setAge(23);
        //int i = student.hashCode();
       // Class<? extends Student> aClass = student.getClass();
        String s = student.toString();
        System.out.println(s);
        System.out.println(student);
        //两者结果一样:org.westos.demo2.Student@61bbe9ba

        /*
        *    public String toString() {
                 return getClass().getName() + "@" + Integer.toHexString(hashCode());
           }
        *
        * */
        //我们觉得父类的toString()老是获取对象的地址值,我觉得意义不大,我想要获取我认为有意义的数据。比如我们想要看我的成员变量的值是什么,觉得有意义

    }
}

子类重写了父类的tostring方法:

public class Student extends Object{
    private String name;
    private int age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

   /* @Override
    public String toString() {
        return "姓名:"+this.name+"==年龄:"+this.age;
    }*/

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

//输出结果:Student{name='张三', age=23}

当打印一个对象时,没打印地址值,说明该方法被重写了。例如:Scanner方法被重写了:

public class MyTest3 {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
         //1.地址值。 2.其他的
         //以后,当你输出一个对象名的时候,如果输出的不是地址值,说明该类重写过toString();
        System.out.println(scanner);

    }
}

11.21_常见对象(Object类的equals()方法)(掌握)

A:案例演示
	a:指示其他某个对象是否与此对象“相等”。 
		源代码: 	
				public boolean equals(Object obj) {
    					return (this == obj);
				}
	b:默认情况下比较的是对象的引用是否相同。
	c:由于比较对象的引用没有意义,一般建议重写该方法。一般用于比较成员变量的值是否相等
	d:==和equals()的区别。(面试题):
	     // == 和 equals()方法的区别
        // == 是比较运算符,可以比较基本数据类型,也可以比较引用数据类型。
       // == 比较基本数据类型,比较的是两个值是否相等。
      // == 比较的是引用数据类型,比较的是两个对象的地址值是否相同
public class MyTest3 {
    public static void main(String[] args) {
        Student s1 = new Student("崔继轩", 18);
        Student s2 = new Student("卢佳苗", 19);
        System.out.println(s1);
        System.out.println(s2);
        // == 他比如是比较引用类型,比较的是两个对象的地址值是否相同
        System.out.println(s1==s2); //false

        //equals() 默认也是在比较两个对象的地址值是否相同
        boolean b = s1.equals(s2);
        /*
        public boolean equals (Object obj){
            return (this == obj);
        }
         */
        System.out.println(b);
    }
}
public class MyTest4 {
    public static void main(String[] args) {
        Student s1 = new Student("崔继轩", 18); //name  age
        Student s2 = new Student("崔继轩", 18);
        //Object类中的equals()方法,默认是比较两个对象是否相等,
        //但是有的时候,我们的子类认为,老是比较两个对象的地址值,是否相同意义不大
        //子类想比较一些,他认为有意义的东西,比如我们自定义的这个Student类认为,只要两个对象的成员变量值一样,就认为这两个对象相同


        boolean b = s1.equals(new Dog()); //ClassCastException

        boolean b2 = s1.equals(s1);
        //比较性能:
        System.out.println(b);
        System.out.println(b2);
    }
}

class Dog{

}

11.22_常见对象(Object类的equals()方法代码优化)(掌握)

A:案例演示
	Object类的equals()方法代码优化
		a: 提高效率
		b: 提高健壮性(instanceof)	
B:最终版
	自动生成
public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    //以后你定义一个方法时,得从方法健壮性(考虑周全),性能方面的提升。
    @Override
    public boolean equals(Object obj) { //Object obj=s2; s2 dog
        if(this==obj){
            return true;
        }
        //判断传过来的这个对象,是不是学生类型,如果是学生类型,我就向下转型,如果不是直接返回false
        //instanceof 判断一个对象或引用,是不是该类型的一个引用
        if(!(obj instanceof Student)){
            return false;
        }
        //比较两个对象的成员变量值是否一样。
        //obj.name 多态形式访问成员变量,编译看左边,运行也看左边。
        //向下转型
        Student s2= (Student) obj;
        //"崔继轩"=="崔继轩" 比较的是地址值 如果是比较两个字符串,字面上的内容是否相同,我们用equals()
         //boolean f = "崔继轩".equals("崔继轩");
        //String 类重写了equals方法来比较两个字符串字面上的内容是否相同
        return this.name.equals(s2.name)&&this.age==s2.age;

    }
   
}

11.23_常见对象(Object类的clone() 方法)(掌握)

​ clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把该方法的权限修饰符改为public
对象的浅克隆:浅克隆和深克隆
​ 使用clone()方法采用的是浅克隆的方式

对象浅克隆要注意的细节: 

		1. 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。
		2. Cloneable接口只不过是一个标识接口而已,没有任何方法。
		3. 对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把
      		另外一个对象也克隆一份。
		4. 对象的浅克隆也不会调用到构造方法的。

对象的深克隆(后面讲):采用IO流来实现  使用 ObjectOutputStream 将对象写入文件中,然后再用ObjectInputStream读取回来

在这里插入图片描述
浅克隆:只克隆了0X001
深克隆:克隆了0X001和0X002

	public class MyTest {
    public static void main(String[] args) throws CloneNotSupportedException {
        DogFood dogFood = new DogFood("王中王");
        Dog dog = new Dog("小白", 2, dogFood);
        dog.dogFood.name="金锣";
         //调用clone()方法属于浅克隆
        //对象的浅克隆:就是克隆一个对象的时候,
        //如果被克隆的对象中维护了另外一个类的对象,
        //这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
        Dog dog1= (Dog) dog.clone();
        dog1.name="小黑";
        dog1.dogFood.name="双汇";

        System.out.println(dog.name); //小白
        System.out.println(dog.age); //2
        System.out.println(dog.dogFood.name);//双汇

        System.out.println("==========================");
        System.out.println(dog1.name);//小黑
        System.out.println(dog1.age);//2
        System.out.println(dog1.dogFood.name); //双汇
    }
}
class Dog implements Cloneable {
    String name;
    int age;
    DogFood dogFood;
    public Dog() {
    }
    public Dog(String name, int age, DogFood dogFood) {
        this.name = name;
        this.age = age;
        this.dogFood = dogFood;
    }

    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone(); //继续调用父类的克隆逻辑
    }
}
class DogFood{
    String name;

    public DogFood(String name) {
        this.name = name;
    }
}

11.23_day11重点总结

Object类的equals 方法是默认比较两个对象是否相等,但是有时候我们的子类认为,老是比较两个对象的地址值是否相同意义不大。

子类想比较一些他们认为有意义的东西,比如我们自定义的Student类认为,只要两个对象的成员变量值一样。

如果是比较两个字符串的字面内容是相同,我们用equals()。String类重写了equals方法来比较两个字符串字面上的内容

instanceof----判断一个对象或引用是不是一个该类型的一个引用----obj instanceof Student

以后你定义一个方法时,得从方法的健壮性(周全)先考虑,性能方面的优化

==和equals方法的区别:

==是比较运算符,可以比较基本数据类型,也可以用来比较引用数据类型;比较基本数据类型:比较的是两个值是否相等;比较的是引用数据类型:比较的是两个对象的地址值是否相同。

equals是Objetc类中的一个方法,默认比较的是两个对象的地址值是否相同,但是有些类会重写Object类中的equals()方法,去比较他认为的有用的东西。比如String类,他也重写了父类的equals()方法,比较的是两个字符串,字面上的内容是否相同。如果使我们自定义的类型,一般会重写,去比较两个对象的成员变量值是否一样。

Favorites—书签–ctrl 点

//TODO 。。。在下方RUn的旁边能找到

标记接口–Cloneable—接口中没有任何方法,就是给类打一个标记,告诉JVM可能要实现某种操作,让JVM能支持某种操作。

克隆一个对象时,需要注意以下两点:

  1. Object类中的克隆方法是个受保护的方法,为了能够调用到,我们可以让这个类重写克隆方法,把方法的权限修饰符改为public
  2. 为了克隆能够被支持,需要该类实现Cloneable这个标记接口

注意:克隆时不调构造方法

两个概念:深克隆、浅克隆

调用clone()属于浅克隆:就是只克隆了一个对象的地址值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值