常用类---Object

本文介绍了Java中Object类的重要角色和方法,包括作为所有类的父类,提供clone方法实现对象复制(浅层和深层复制的示例),以及equals和hashCode方法的用途和重写规则。同时,解释了toString方法在对象表示上的作用和重写方法。
摘要由CSDN通过智能技术生成

一、object概述

1、什么是object

objest是所有类的直接或间接父类,位于继承树的最顶层,我们在新建类的时候,会默认继承该父类而不需要些
关键字

2、object的作用

➢提供了很多有用的方法
➢可以让我们书写方法的时候,返回类型或者参数类型用Object,方便接收任何类型的数据

二、object的有用的方法

1、clone

1.1、介绍

➢能让对象实现复制的功能(注意,这个复制默认是浅层复制,如果想要进行深层复制,我们需要手动书写里面的方法逻辑);
➢要想实现克隆的功能,就需要让你要实现的对象所在的类去实现CloneAble接口;
➢CloneAble接口里面提供了一个clone的方法,该方法默认已经完成了复制功能;
➢clone方法调用之后,返回的是一个0bject对象, 所以我们需要进行强转为我们需要的类型;

1.2、浅层复制 demo

a、让你要实现复制的类来实现一个Cloneable接口;

b、重写clone方法,里面不需要写任何的代码,默认即可;

c、调用该clone方法;

d、返回的是Object类型,进行强转;

public class CloneDemo {
    public static void main(String[] args) throws CloneNotSupportedException {
        Person p1 = new Person(1001,"张三");

        Person p2 = (Person)p1.clone();
        //复制完成之后,更改p1里面的内容,看是否会影响到p2
        p1.pid = 1002;

        System.out.println(p1.pid+","+p1.pname);
        System.out.println(p2.pid+","+p2.pname);
        //查看这两个对象的地址值是否相同
        System.out.println(p1==p2);

    }
}
class Person implements Cloneable{
    int pid;
    String pname;

    public Person() {
    }
    public Person(int pid, String pname) {
        super();
        this.pid = pid;
        this.pname = pname;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}

1.2、浅层复制图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TMjP6vge-1687177343386)(001-object.assets/image-20210814113348169.png)]

1.3、深层复制demo

a、如果要单独进行深层复制的话,那么就证明当前对象里面的属性肯定拥有

基本数据类型和字符串之外的属性(引用类型)存在;

b、对这个自定义数据类型的类来实现Cloneable接口

c、重写里面的clone方法,里面内容不用改,默认即可;

d、在需要进行深层复制的对象的clone方法里面进行手动书写,书写的目的在于

手动调用它里面的自定义属性的clone方法;

public class CloneDemo {
   public static void main(String[] args) throws CloneNotSupportedException {
   	Person p1 = new Person(1001,"张三");
   	//为当前对象加入一个新的Address属性
   	Address address = new Address("家庭","湖南长沙");
   	p1.address = address;
   	Person p2 = (Person)p1.clone();
   	//复制完成之后,更改p1里面的内容,看是否会影响到p2
   	p1.pid = 1002;
   	p1.address.type = "公司";
   	System.out.println(p1.pid+","+p1.pname+","+p1.address.type+","+p1.address.location);
   	System.out.println(p2.pid+","+p2.pname+","+p2.address.type+","+p2.address.location);
   	//查看这两个对象的地址值是否相同
   	System.out.println(p1==p2);
   	//查看address是否是同一个对象,如果为true,就是浅层复制
   	System.out.println(p1.address==p2.address);
   }
}
class Person implements Cloneable{
   int pid;
   String pname;
   //加上自定义数据类型Address
   Address address;
   public Person() {
   }
   public Person(int pid, String pname) {
   	super();
   	this.pid = pid;
   	this.pname = pname;
   }
   @Override
   protected Object clone() throws CloneNotSupportedException {
   	//1、拿到返回的Person对象
   	Person person = (Person)super.clone();
   	//2、拿到该对象里面的Address属性
   	Address address = person.address;
   	//3、针对该属性来进行一个clone
   	Address newAddress = (Address)address.clone();
   	//4、把克隆完成之后的address对象放回你要返回的Person对象内部
   	person.address = newAddress;
   	return person;
   }
}
class Address implements Cloneable{
   String type;//地址的类型,比如家庭还是公司
   String location;//地址的具体位置
   public Address() {
   }
   public Address(String type, String location) {
   	super();
   	this.type = type;
   	this.location = location;
   }
   
   @Override
   protected Object clone() throws CloneNotSupportedException {
   	// TODO Auto-generated method stub
   	return super.clone();
   }
}

1.3、深层复制图解

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZNKiF9c1-1687177343387)(001-object.assets/image-20210814113409655.png)]

2、equals

2.1、equals介绍

在java中比较对象有两种方式

  • 第一种:双等号,比较的是对象的地址值是否相同
  • 第二种:equals,用来比较对象里面的内容是否相同

但是object类中的equals方法是模版方法,字类必须重写equals方法

2.2、equals重写的思路

比较两个引用是否指向同-一个对象。
判断obj是否为null。
判断两个引用指向的实际对象类型是否一 致。
强制类型转换。
依次比较各个属性值是否相同。

注意:如果你一个类中拥有另外一个自定义数据类型的属性的话

你要重写equals就必须提前先把那个属性里面的equals也重写了;

2.3、equals 重写代码

public class EqualsDemo {
    public static void main(String[] args) {
        Book b1 = new Book(1001, "红楼梦");
        Book b2 = new Book(1001, "红楼梦");
        //使用==和equals分别进行判断
        System.out.println(b1 == b2);//false
        System.out.println(b1.equals(b2));//true
    }
}

class Book {
    int bid;
    String bname;

    public Book() {
    }

    public Book(int bid, String bname) {
        super();
        this.bid = bid;
        this.bname = bname;
    }

    public boolean equals(Object obj) {
        //1、判断两个对象是否指向的是同一个
        if (this == obj) {
            return true;
        }
        //2、判断obj是否为null
        if (obj == null) {
            return false;
        }
        //3、判断两个对象是否是同一个类型
        if (this.getClass() != obj.getClass()) {
            return false;
        }
        //4、类型转换
        Book other = (Book) obj;
        //5、进行里面属性的一个个的判断
        return this.bid == other.bid && this.bname.equals(other.bname);
    }


}

2.4、 自动生成

3、hashcode

3.1、hashcode 介绍

➢Java中的hashcode方法作用就是在我们往堆里面/容器里面放入一个对象之前,先判断这个对象是否存在,虽然我们可以通过equals来进行判断,但是一个个判断效率太过于低下,所以Sun公司就给出规范,内容相同对象的hashcode值一定相同。这个hashcode值,我们称之为哈希码值,也叫散列值;

(内容可以看作对象中的属性值要一致,并非所有属性都要一致,选取自己需要的)
散列值是怎么算出来的:根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为哈希码值。
默认的hashcode方法的哈希码并不唯一, 我们需要重写该方法,来可保证相同对象(内容相同)返回相同哈希码,尽量保证不同对象返回不同哈希码
➢我们一般直接调用0bjects.hashcode方法来完成该方法的重写,当然,你也可以书写一个方法,只要该方法可以通过对象里面的属性值来算出一个数值出来,并且能保证不同的对象这个数值不相同;
➢我们为了按照Sun公司的建议,一般来说, equals为true, 那么它们的hashcode值也要一定相等 ,所以我们在重写hashcode方法的时候,请务必把该方法里面所用到的属性和equals方法所用到的属性保持一致

3.2、hashcode 重写

a、hashcode默认是0bject类中的方法,这个方法不能保证不同的对象拥有不同的hashcode值;
b、我们书写hashcode方法需要遵循的原则是,hashcode通过哪些具体的属性来算出来要和 equals判断的属性保持一致, 比如说equals方法的return后面用了一个类中的3个属性的2个属性 那么,hashcode方法也只需要使用这两个即可;
C、我们一般不手动去书写该方法,直接调用0bjects. hash即可;

public class EqualsDemo {
    public static void main(String[] args) {
        Book b1 = new Book(1001,"红楼梦");
        Book b2 = new Book(1001,"红楼梦");
        //查看这两个对象的hashcode值
        System.out.println(b1.hashCode());
        System.out.println(b2.hashCode());
    }
}
class Book{
    int bid;
    String bname;
    public Book() {
    }

    public Book(int bid, String bname) {
        super();
        this.bid = bid;
        this.bname = bname;
    }

    @Override
    public int hashCode() {

        return Objects.hash(bid,bname);
    }

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



3、tostring

3.1、tostring方法介绍

➢Java中的对象进行输出的话,会默认调用Object类的toString方法,而该方法的底层其实就是输出该对象的全限定名+该对象的的hashcode值,这个数值对于我们开发者来说其实并没有含义,而我们更喜欢在输出对象的时候,能输出当前对象的一些属性,让我们更加方便的识别该对象;
➢重写0bject类的toString方法, 就是让我们输出对象的时候,可以按照你想要展示的样式来输出对象

3.2、tostring重写

	@Override
	public String toString() {
		return "Book [bid=" + bid + ", bname=" + bname + "]";
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值