在java中,所有的类都有一个公共的父类,这个java.lang.Object类
* * * Object所有类的根,成为超类。
1.证明Object是根
public class A_Object01 {
public static void main(String[] args) {
//证明Object是根
//基本数据类型
int a = 0;
Object bytea = 2;
Object shorta = 125;
Object inta = 235;
Object longa = 123455677;
Object floatb = 12.8f;
Object doublea = 123.456;
Object chara = '好';
Object booleana = true;
//引用类型
Object string = "String";
Object arr1 = new String[5];
Object arr2 = new Father[5];
/*
以上代码段都没有报错 可以证明Object是根
*/
}
}//我们创建一个类时,如果没有明确继承一个父类,
// * 那么它就会自动继承 Object,成为 Object 的子类。
class Father {
}
2.Object类的其中5个方法
(1)toString()
①默认情况下,toString()返回的是“对象的运行时所属类型 @ 对象的hashCode值的十六进制形式" ②如果我们直接System.out.println(对象),默认会自动调用这个对象的toString()
public static void main(String[] args) {
// 1.未重写toString方法
/* ToString02 obj1=new ToString02();
System.out.println(obj1.toString());//day0419.arrange_and_summarize.object01.ToString02@1b6d3586
*/
/*
* 注意:一般情况下,我们需要的是结果值,而不是地址值。如何获取结果值呢?
* 进行重写toString()方法后就可以拿到结果值
* */
//2.重写toString
ToString02 obj1=new ToString02("重写toString",87);
System.out.println(obj1.toString());//输出ToString02{name='重写toString', age=87}
}
(2)getClass()
public final Class<?> getClass():获取对象的运行时类型
因为Java有多态现象,所以一个引用数据类型的变量的编译时类型与运行时类型可能不一致,因此如果需要查看这个变量实际指向的对象的类型,需要用getClass()方法
public class TestGetClass05 {
public static void main(String[] args) {
/*1. GetClass04类
GetClass04 obj1=new GetClass04("GetClass04类",18);
System.out.println(obj1.getClass());//class day0419.arrange_and_summarize.object01.GetClass04*/
//返回该对象对应的类
//2.OBJECT类
Object obj2 = new GetClass04("OBJECT类", 18);
System.out.println(obj2.getClass());//class day0419.arrange_and_summarize.object01.GetClass04
//编译时是父类(Object),运行时是子类(Student03)}
(3)equals()
1. 重写equals原因 equals: 用于判断当前对象this与指定对象obj是否“相等” ①在默认情况下,equals方法的实现等价于与“==”,比较的是对象的地址值 ②但是我们想要的是当前对象this与指定对象obj是否“相等”,如何解决呢? 答:重写equals方法
public class TestEquals07 {
public static void main(String[] args) {
Equals06 obj1 = new Equals06("obj1", 18);
Equals06 obj2 = new Equals06("obj1", 18);
Equals06 obj3 = new Equals06("obj3", 14);
Equals06 obj4 = obj1;
/*1.未重写*/
// 1.1未重写equals
/* System.out.println(obj1.equals(obj2));//false
System.out.println(obj1.equals(obj3));//false
System.out.println(obj2.equals(obj3));//false
System.out.println(obj4.equals(obj1));//true*/
//1.2未重写hashCode方法
/* System.out.println(obj1.hashCode());//460141958
System.out.println(obj2.hashCode());//1163157884
System.out.println(obj3.hashCode());//1956725890
System.out.println(obj4.hashCode());//460141958*/
/*
注意: 1. 重写equals原因
equals: 用于判断当前对象this与指定对象obj是否“相等”
①在默认情况下,equals方法的实现等价于与“==”,比较的是对象的地址值
②但是我们想要的是当前对象this与指定对象obj是否“相等”,如何解决呢?
答:重写equals方法
*/
/*2.重写*/
// 2.1重写equals
System.out.println(obj1.equals(obj2));//true
System.out.println(obj1.equals(obj3));//false
System.out.println(obj2.equals(obj3));//false
System.out.println(obj4.equals(obj1));//true
//2.2重写hashCode方法 重写后使hashcode一致
System.out.println(obj1.hashCode());//105534713
System.out.println(obj2.hashCode());//105534713
System.out.println(obj3.hashCode());//105534713
System.out.println(obj4.hashCode());//105534713
}
}
(4)hashCode()
public int hashCode():返回每个对象的hash值。
如果重写equals,那么通常会一起重写hashCode()方法,hashCode()方法主要是为了当对象存储到哈希表(后面集合章节学习)等容器中时提高存储和查询性能用的,这是因为关于hashCode有两个常规协定:
-
①如果两个对象的hash值是不同的,那么这两个对象一定不相等;
-
②如果两个对象的hash值是相同的,那么这两个对象不一定相等。
-
public class TestHashCode09 { public static void main(String[] args) { HashCode08 obj1=new HashCode08("obj1",18); HashCode08 obj2=new HashCode08("obj1",18); HashCode08 obj3=obj1; //1.未重写hashCode方法 /* System.out.println(obj1.hashCode());//460141958 System.out.println(obj2.hashCode());//1163157884 System.out.println(obj3.hashCode());//460141958*/ /* 如果根据 equals()方法,两个对象是相等的, 那么对这两个对象中的每个对象调用 hashCode方法都必须生成相同的整数结果; 而两个hashCode()返回的结果相等,两个对象的equals()方法不一定相等。 */ //2.重写hashCode方法 System.out.println(obj1.hashCode());//105534713 System.out.println(obj2.hashCode());//105534713 System.out.println(obj3.hashCode());//105534713 /* 注意: - ①如果两个对象的hash值是不同的,那么这两个对象一定不相等; - ②如果两个对象的hash值是相同的,那么这两个对象不一定相等。 ( 都是String对象,而且是不同的对象,但是在某种情况下hashcode有可能相等,十进制 位置有限) */ System.out.println("❤❤❤❤❤❤❤❤❤❤❤❤❤❤"); // ①如果两个对象的hash值是不同的,那么这两个对象一定不相等; System.out.println("hello".hashCode());// 99162322 System.out.println("kk".hashCode()); //3424 System.out.println("hello".equals("kk"));//false System.out.println("❤❤❤❤❤❤❤❤❤❤❤❤❤❤"); // ②如果两个对象的hash值是相同的,那么这两个对象不一定相等。 System.out.println("Aa".hashCode());//2112 System.out.println("BB".hashCode());//2112 System.out.println("Aa".equals("BB"));//false } }
总结:
-
使用
hashCode()
来比较两个对象是否相等是不合适的,因为确实存在不同的对象具有相同hashCode
值的可能性。这种情况被称为哈希冲突,是哈希表等数据结构必须处理的一种情况。 -
当你需要比较两个对象是否相等时,应该使用
equals()
方法而不是hashCode()
方法。 -
如果两个对象根据
equals()
方法是相等的,那么它们的hashCode()
方法应该返回相同的值,这是Java对象的一个基本要求。但是,反过来并不成立:即使两个对象的hashCode()
值相同,它们也可能不相等。 -
所以,在编写Java代码时,如果你重写了
equals()
方法,通常也应该重写hashCode()
方法,以确保它们的行为一致。这样可以确保当两个对象根据equals()
方法相等时,它们的哈希码也相同,但是,不要仅仅依赖hashCode()
来比较对象的相等性。
(5)finalize() (了解)
protected void finalize():用于最终清理内存的方法
面试题:对finalize()的理解?
-
当对象被GC确定为要被回收的垃圾,在回收之前由GC帮你调用这个方法,不是由程序员手动调用。
-
这个方法与C语言的析构函数不同,C语言的析构函数被调用,那么对象一定被销毁,内存被回收,而finalize方法的调用不一定会销毁当前对象,因为可能在finalize()中出现了让当前对象“复活”的代码
-
每一个对象的finalize方法只会被调用一次。
-
子类可以选择重写,一般用于彻底释放一些资源对象,而且这些资源对象往往时通过C/C++等代码申请的资源内存
-
(6)重写toString、equals和hashCode方法(Alt+Insert)
建议使用IDEA中的Alt + Insert快捷键,而不是Ctrl + O快捷键。
3.标准JavaBean
JavaBean
是 Java语言编写类的一种标准规范。符合JavaBean
的类,要求:(1)类必须是具体的和公共的,
(2)并且具有无参数的构造方法,
(3)成员变量私有化,并提供用来操作成员变量的
set
和get
方法。(4)重写toString方法