18.Object类及其常用方法

Object类的学习

**引言:**Object类作为所有类的超类,有一些方法是值得研究的。因为这些方法是所有子类都继承了的。(任何一个子类,都会直接或间接继承Object类)

此外,有两种方法查看常用类的常用方法:

  1. 查看Sun公司写的源码
  2. 通过API帮助文档

什么是API?Application Program Interface

应用程序编程接口

整个JDK的类库就是一个Java SE的API。

每一个API都会配置一套API帮助文档

1. Object类中有哪些常用方法?

  1. protected Object clone(){}// 负责对象克隆的
  2. int hashCode(){}//获取对象哈希值的一个方法
  3. boolean equals(Object obj){}//判断两个对象是否相等
  4. String toString(){}//将对象转换成字符串形式
  5. protected void finalize(){}// 垃圾回收器负责调用的方法

1).toString() 方法

1. toString源代码长什么样
public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }
2. toString 方法的作用

toString()方法的设计目的是:通过调用这个方法可以将一个“Java对象”转换成“字符串表示形式”。

3.重写 toString方法
public class Test01{
	public static void main(String[] args){
		MyTime m = new MyTime(2021,4,21);
		//重写toString方法之前
		//System.out.println(m);//MyTime@4517d9a3
		//实际上我不想显示对象的地址,我想显示具体的内容
		//那么考虑重写MyTime类的toString方法
		System.out.println(m);//2021年4月21日
		//输出引用会自动调用toString方法(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;
	}
    //重写toString方法
	public String toString(){
		return this.year+"年"+this.month+"月"+this.day+"日";
	}
}

2).equals方法

1.源码长啥样?

//显然,判断时用的是 == ,无法比较两个对象的实际内容是否一致,只能比较两个引用的地址是否一致。

public boolean equals(Object obj) {
        return (this == obj);
    }
2. equals的作用?

以后编程的过程当中,都要通过equals方法来判断两个对象是否相等。
equals方法是判断两个对象是否相等的

public class Test02{
	public static void main(String[] args){
		int i = 100;
		int j = 100;
		System.out.println(i == j);//true
		MyTime m1 = new MyTime(2021,4,21);//m1:0x1111
		MyTime m2 = new MyTime(2021,4,21);//m2:0x2222
		System.out.println(m1 == m2);//false,
		//这里只是比较了两个引用存放的对象的地址,显然是不同的
	    //调用重写之前的equals方法
		//System.out.println(m1.equals(m2));//false,
		//从源码看出继承的equals方法仍然使用 == 判断
		//要比较对象的内容,只能考虑重写equals方法
		System.out.println(m1.equals(m2));//true
		m2 = null;
		System.out.println(m1.equals(m2));//false
		MyTime m3 = new MyTime(2021,4,22);
		System.out.println(m1.equals(m3));//false


	}
}
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) {
		//保存第一个对象的年月日
       int year1 = this.year;
	   int month1 = this.month;
	   int day1 = this.day;
	   //获得第二个对象的年月日
	   if(obj instanceof MyTime){
			MyTime t = (MyTime)obj;
			int year2 = t.year;
			int month2 = t.month;
			int day2 = t.day; 
			if(year1 == year2 && month1 == month2 && day1 == day2)
				return true;
		}
		return false;

    }
	*/
	public boolean equals(Object obj){
		//如果obj为空,或者不是同一类型的对象,直接返回flase
		if(obj == null || !(obj instanceof MyTime))
			return false;
		if(obj == this)
			return true;//说明是同一个对象
		MyTime t = (MyTime)obj;//向下转型是多态机制的体现,即obj指向的对象可以是Mytime类型的,但是编译过程中obj是Object类型的,显然Object类型中并没有year,month,day这三个属性,所以进行向下转型。
		return t.year == this.year && t.month == this.month && t.day == this.day;
	}

}

2. String类是否重写了toString和equals方法?

重写了

/*
	java语言当中的字符串String有没有重写toString方法,有没有重写equals方法。

	总结:
		1、String类已经重写了equals方法,比较两个字符串不能使用==,必须使用equals。
		equals是通用的。

		2、String类已经重写了toString方法。
	
	大结论:
		java中什么类型的数据可以使用“==”判断
			java中基本数据类型比较是否相等,使用==

		java中什么类型的数据需要使用equals判断
			java中所有的引用数据类型统一使用equals方法来判断是否相等。
		
		这是规矩。
*/
public class Test03{
	public static void main(String[] args){

		// 大部分情况下,采用这样的方式创建字符串对象
		String s1 = "hello";
		String s2 = "abc";

		// 实际上String也是一个类。不属于基本数据类型。
		// 既然String是一个类,那么一定存在构造方法。
		String s3 = new String("Test1");
		String s4 = new String("Test1");
		// new两次,两个对象内存地址,s3保存的内存地址和s4保存的内存地址不同。
		// == 判断的是内存地址。不是内容。
		System.out.println(s3 == s4); // false

		// 比较两个字符串能不能使用双等号?
		// 不能,必须调用equals方法。
		// String类已经重写equals方法了。
		System.out.println(s3.equals(s4)); // true

		// String类有没有重写toString方法呢?
		String x = new String("动力节点");
		// 如果String没有重写toString()方法,输出结果:java.lang.String@十六进制的地址
		// 经过测试:String类已经重写了toString()方法。
		System.out.println(x.toString()); //动力节点
		System.out.println(x); //动力节点
	}
}

练习

字符串比较只能使用equals方法,正好String类中重写了equals方法!!!

public class Test01 {
    public static void main(String[] args) {
        Student s1 = new Student(10,"张三");
        Student s2 = new Student(10,"张三");
        System.out.println(s1.equals(s2));
    }
}
class Student{
    int no;
    String name;

    public Student() {
    }

    public Student(int no, String name) {
        this.no = no;
        this.name = name;
    }
    //重写toString方法
    @Override
    public String toString() {
        return "学号:"+this.no+", 姓名:"+this.name;
    }
    //重写equals方法


    @Override
    public boolean equals(Object obj) {//多态
        if(obj == null || !(obj instanceof Student))
            return false;
        if(obj == this)
            return true;
        Student s =(Student)obj;
        return s.no == this.no && this.name.equals(s.name);//这里的qequals调用的是字符串String类的equals方法
    }
}

注意:

equals方法的调用层层嵌套,所以equals方法的重写要彻底

public class Test04{//euqals方法会层层嵌套,所以equals方法重写要彻底
	public static void main(String[] args){
		User u1 = new User("张三",new Address("北京","朝阳区","1111"));
		User u2 = new User("张三",new Address("北京","朝阳区","1111"));
		System.out.println(u1.equals(u2));
	}
}
class User{
	String name;
	Address addr;
	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(this == obj) return true;
		//转换
		User u = (User)obj;
		return this.name.equals(u.name) && this.addr.equals(u.addr);//会继续调用引用类型属性的equals方法
	}
}
class Address{
	String city;
	String street;
	String zipcode;
	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 Address))
			return false;
		if(this == obj)
			return true;
		//转换
		Address a =(Address)obj;
		return this.city.equals(a.city) && this.street.equals(a.street) && this.zipcode.equals(a.zipcode);//继续调用String类型的equals方法
	}

}

3. Object类中有哪些常用方法(2)?

1). finalize 方法

  1. 源码(已经过时了)

本方法只有空方法体,没有代码。并且该方法由protected修饰!

protected void finalize() throws Throwable { }
  1. finalize方法的使用

本方法不需要手动调用,是Sun公司提供的一个垃圾回收时机,JVM的垃圾回收器负责调用该方法,如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法当中。

  1. finalize 方法的执行时机:

当一个对象被垃圾回收器回收的时候,垃圾回收器负责调用finalize方法

  1. 提示:

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

2). int hashCode() 方法

  1. 源码

这个方法不是抽象方法,带有native关键字,底层调用C++程序。

public native int hashCode();
  1. hashCode()方法返回的是哈希码:
    实际上就是一个Java对象的内存地址,经过哈希算法,得出的一个值
    所以hashCode()方法的执行结果可以等同看做一个Java对象的内存地址。
public class Test05{
	public static void main(String[] args){
		Object o = new Object();
		System.out.println(o.hashCode());//617901222
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值