千峰Java教程:063. Object类

本文围绕Java的Object类展开,介绍其是类层次结构的根类,所有类都是它的子类。详细讲解了toString和equals方法,包括方法作用、特性,还举例说明重写方法的必要性。此外,还提及finalize和getclass方法,其他方法将在后续章节讲解。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

14、Object类

Object类 是类层次结构的跟类

每个类都是用Object作为超类。所有对象(包括数组)都实现这个类的方法。

 

所有类都是Object类的子类。

 

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

通常,toString方法会返回一个“以文本方式表示”此对象的字符串。结果应是一个简明且易于读懂的信息表达式。建议所有子类都重写此方法。

 

public boolean equals(Objects obj)方法:指示其他某个对象是否与此对象“相等”。equals方法在非空对象引用上实现相等关系:

自反性:对于任何非空引用值x,x.equals(x)都行返回true。

对称性:对于任何非空引用值x、y,当且仅当y.equals(x)返回true时,x.equals(y)返回true。

传递性:对于任何非空引用值x、y和z,如果x.equals(y)返回true,并且y.equals(z)返回true时,那么x.equals(z)就返回true。

一致性:对于任何非空引用值x、y,多次调用x.equals(y)返回true或返回false,前提是对象上equals比较中所用的信息没有被修改。

对于任何非空引用值x,x.equals(null)都应返回false(因为既然有:x.equals(null),就一定能说明x非空)。

public class Demo1
{
	public static void main(String[] args)
	{
		Student s = new Student();
		System.out.println(s.toString());
	}
}

class Student
{
	private String name;
	private int sid;
	private int age;
	public Student(){}
	public Student(int sid, String name, int age)
	{
		this.sid = sid;
		this.name = name;
		this.age = age;
	}
}
/*其实这个时候Student是一个类的子类,其父类是Object类。其结果为:
Student@7852e922
*/

我们可以看到,在下面的类中,没有toString()的方法,怎么会输出toString()呢?我们打开jdk1.8.0_192\java\lang\,打开Object.java,在里面找到有这样的代码(我这个代码是在235行):

来分析一下这段代码,它返回的是getName,指的是我们创建的子类(Student)名,中间输出一个@,后面输出的是一串数字字母组合的代码。Hex:16进制。所以现在我们都不懂这个信息,所以建议所有子类都重写此方法(此方法:toString()方法)。

我们把上面我写的类中的代码改一下,在类里面添加toString()方法:

public class Demo1
{
	public static void main(String[] args)
	{
		Student s = new Student(1, "飞飞", 18);
		System.out.println(s.toString());
	}
}

class Student
{
	private String name;
	private int sid;
	private int age;
	public Student(){}
	public Student(int sid, String name, int age)
	{
		this.sid = sid;
		this.name = name;
		this.age = age;
	}
	public String toString()    //这个是把父类的toString方法重写了,返回的是学号、名字、年龄
	{
		return "SID = "+sid+", Name = "+name+", Age = "+age;
	}
}
/*
结果:
SID = 1, Name = 飞飞, Age = 18
*/

当然我们在主函数输出语句中把s.toString()改成s,它会默认输出的,还是SID = 1, Name = 飞飞, Age = 18.

我们再看Object类的equals方法:

首先自反性,上面说给定非空引用值x,x.equals(x)会返回true,我们来试试:

public class Demo1
{
	public static void main(String[] args)
	{
		Student s1 = new Student(1, "飞飞", 18);
		Student s2 = new Student(2, "备备", 20);
		System.out.println(s1.equals(s1));
		System.out.println(s1.equals(s2));
	}
}

class Student
{
	private String name;
	private int sid;
	private int age;
	public Student(){}
	public Student(int sid, String name, int age)
	{
		this.sid = sid;
		this.name = name;
		this.age = age;
	}
	public String toString()
	{
		return "SID = "+sid+", Name = "+name+", Age = "+age;
	}
}
/*
结果:
true
false
*/

可以看到,s1的地址是一个地址,所以s1.equals(s1),自己跟自己比较。当然返回true;s1跟s2地址不同,s1.equals(s2)返回的就是false了。还有,如果把主函数中第六行改成Student s2 = new Student(1, "飞飞", 18);再来比较,返回的还是false,因为地址不同。

好,现在需求来了:当一个对象的所有值都相等的情况下,我们要把它认为是同一个对象。这时候我们就要重写equals方法了,首先我们在jdk1.8.0_192\java\lang\中打开Object.java,在148行,有这样一段代码,就是equals的源代码:

我们按照要求重写这个代码,看到上面这个截图,考虑的是地址之间的比较,地址不同,返回的就是false,相同返回true。我们来写一下另一个代码:

public class b
{
	public static void main(String[] args)
	{
		String str1 = new String("刘备");
		String str2 = new String("刘备");
		System.out.println(str1.equals(str2));
	}
}
/*
结果:
true
*/

这时,可以看到在String中,改写了equals的方法,我们在同目录的String.java下找一下改写的equals代码:

public boolean equals(Object anObject) {
        if (this == anObject) {//首先第一个判断,如果地址相同,直接可以返回true,要是不同,返回false
            return true;
        }
        if (anObject instanceof String) {//然后地址不同的话,如果传进来的obj不是String类型,将其转换成String类型,名字叫anotherString
            String anotherString = (String)anObject;
            int n = value.length;//那就等于anotherString的长度
            if (n == anotherString.value.length) {//如果长度相等
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {//n从大到下往下循环,看下面的if,如果其中有一个Ascii码不对,则返回false,不然就返回true
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

依照上面的来说,我们可以改一下我们的代码,看看看输出效果:

public class Demo1
{
	public static void main(String[] args)
	{
		Student s1 = new Student(1, "飞飞", 18);
		Student s2 = new Student(1, "飞飞", 18);
		System.out.println(s1.equals(s2));
		//System.out.println(s1.equals(s2));
	}
}

class Student
{
	private String name;
	private int sid;
	private int age;
	public Student(){}
	public Student(int sid, String name, int age)
	{
		this.sid = sid;
		this.name = name;
		this.age = age;
	}
	
	public String toString()
	{
		return "SID = "+sid+", Name = "+name+", Age = "+age;
	}
	
	public boolean equals(Object obj)	//重写equals方法,来实现两个对象的比较
	{
		if(this == obj)	//如果对象地址是它自己,可以直接返回true
		{
			return true;
		}
		if(obj instanceof Student)//如果对象是Student,可以接着判断
		{
			Student newobj = (Student)obj;
			if(this.sid != newobj.sid)//比较一下身份,不对的话返回false
			{
				return false;
			}
			if(this.age != newobj.age)//比较一下年龄,不对的话返回false
			{
				return false;
			}
			if(!this.name.equals(newobj.name))//比较一下名字,不对的话返回false
			{
				return false;
			}
			return true;
		}
		return false;
	}
}
/*
结果:
true
*/

protect void finalize()throwsThrowable

当垃圾回收器确定不存在该对象的更多引用时,对象的垃圾回收器调用此方法。子类重写finalize方法,以配置系统资源或进行其他清除。

public final Class<?> getclass()

返回此Object的运行时类。

 

其他方法在后续章节中讲解。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值