一,Object类的概述
1,每个类都有直接或间接的继承了Object类。
Object类 是类层次结构的跟类,每个类都使用Object作为超类。
所有对象(包括数组)都实现这个类的方法。
我们自定义的任意类的对象都是默认就拥有Object类的所有的方法。
2,方法分类
hashCode() 返回对象的哈希码值
equals(Object obj) 指示其它某个对象是否与此对象“相等”。
toString() 返回该对象的字符串表示
finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此法 (熟悉 面试题)。
getClass() 返回此Object的运行时类 (重要 在后面的反射课程讲解)
clone() 创建并返回此对象的一个副本 (了解)
wait notifl notifyAll 线程交互方法(重要 线程课程讲解)
这个三个方法都属于Object类的,不属于线程类的。
二,hashCode方法
1,API中的介绍
返回该对象的哈希码值,就是这个方法能根据当前对象返回一个值。
2,特点:
A,在java应用程序执行期间,在对同一个对象多次调用hashCode方法时,必须一致的返回相同的整数。
B,从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
不同的程序执行过程,调用hashCode可以返回不同的数值。
C,如果根据equals(Object)方法,两个对象时相等的,那么对这两个对象中的每个对象调用hashCode。方法
必须生成相同的整数。
D,hashCode如果相等,则可以判定两个对象相等(hashCode类似对象的身份证),常用于判断是否同一个对象。
class T1{
}
public class ObjectClassDemo1{
public static void main(String[] args){
//测试同一次执行过程中,调用同一个对象的多次hashCode值,必须一样。
T1 tt=new T1( );
//多次调用 tt 对象的hashCode方法
System.out.println( tt.hashCode( ) );
System.out.println( tt.hashCode( ) );
//以上的输出是在一次执行过程中,对比对象调用多次hashCode方法的返回值是一样的。
//不同的程序执行过程中,hashCode值可以不同
T1 tt1 = new T1( );
System.out.println( tt1 . hashCode( ) );
//常用于判断是否同一个对象
T1 tt1 = new T1( );
T1 tt2 = new T1( );
//输出tt1和tt2的hashCode值
System.out.println( tt1 . hashCode( ) );
System.out.println( tt2 . hashCode( ) );
//由以上输出可以看出不同对象的hashCode值是不同的
T1 tt3 = tt2;//索引值复制
System.out.println( tt2 . hashCode( ) );
System.out.println( tt3 . hashCode( ) );
}
}
三,equals方法
1,== 比较运算符 判断操作
==既可以用于比较基本数据类型,也可以用于比较引用数据类型。
基本数据类型中是用于判定两个变量的具体数值是否相等。
引用数据类型中比较的是两个变量是否指向内存中的同一个地址值。
==对于引用数据类型的比较,用于比较的是地址。
2,equals
equals只能用于引用数据类型的比较判等。
在Object类中的equals方法实际上底层就是使用==进行比较的,就是比较的两个对象的地址是否相等。
3,通常的equals使用方式
eg:
如果在同一个班里,没有相同名称的同学,我就可以认为如果你给我两个学生对象,如果年龄和姓名一样,我就认为是同一个人。
4,equals总结
A,原有的Object类中的equals方法是比较地址值(底层是使用==进行比较)
B,往往在真正做系统时,根据需求重写equals方法。
C,重写equals方法通常和hashCode有关联(两个都需要重写)
hashCode可以认为是对象的身份证号码
equals可以认为是对象的描述信息进行比较
因为身份证号不同,可能名称相同;所以可能会出现hashCode不等,equals相等的情况。
推荐是如果需要重写hashCode或者equals方法的任何一个,就重写另外一个。
D,重写的关键是要根据项目需求找到判等规则。
class Student{
private String name;
private int age;
public Student(){
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
//重写Object类中的hashCode方法和equals方法
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
class T2{ }
public class ObjectClassDemo2{
public static void main(String[] args){
//创建T2类的对象
T2 t1=new T2();
T2 t2=new T2();
//两个对象使用==进行比较
System.out.println(t1==t2);//false
System.out.println(t2==t2);//true
//两个对象使用equals方法比较
System.out.println(t1 . equals( t2 ));//false
System.out.println(t1 . equals( t1 ));//true
//创建两个学生类对象,同名称同年龄
Student st1 =new Student("aaa",20);
Student st2 =new Student("aaa",20);
//按照业务需求,这个两个对象时同一个人,但是方法没有重写。结果会出现问题
System.out.println(t1 . equals( t2 ));//false 没有方法重写
//hashCode和equals方法重写之后
System.out.println(t1 . equals( t2 ));//true
}
}
四,toString方法
1,以字符串的形式返回对象的描述信息。
对象的描述信息就是指对象的外部特征即属性。
2,Object类中的toString方法默认的输出
getClass().getName()+"@"+Integer.toHexString(hashCode())
getClass().getName():类的全名称 带有包名次的类名次
Integer.toHexString(hashCode()):返回对象的hashCode值的十六进制字符串表示形式。
3,toString方法在实际系统中的使用方式
往往会在子类中重写这个toString方法,以输出具有实际意义的字符串。
Object类中的toString方法输出的信息对于实际业务来说没有任何意义,所以
通常都会重写toString方法。
4,直接输出对象,就是调用此对象的toString方法。
class T3{ }
class Teacher{
private String name;
private int age;
public Teacher(){
}
public Teachr(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
//重写的toString方法
public String toString() {
return "Teacher [name=" + name + ", age=" + age + "]";
}
}
public class ObjectClassDemo3{
public static void main(String[] args){
T3 tt=new T3();
System.out.println(tt.toString());//类和包的全名称,还有十六进制的字符串形式
Teacher teacher=new Teacher( );
System.out.println( teacher.toString() );
//重写之前的输出 Object . Teacher@dc5869
//重写toString方法之后的输出
Teacher[name=null; age=0]
}
}
五,finalize方法:
1,它是对象的生命周期方法。
对象被创建之后立即执行的方法: 构造方法
对象在销毁之前立即执行的方法: finalize方法
2,final finally finalize有什么区别?
final:是修饰符,表示最终。
可以修饰类、成员变量、成员方法、局部变量。
fianlly:在异常机制中,必须被执行的代码。
finalize:是Object类的一个方法,在对象被回收之前会被自动调用执行。
六,一个对象的创建步骤:
加载
在第一次使用类之前,需要把class加载入内存
把Object类加载入内存
把父类class文件加载入内存
为父类对象的静态成员变量开辟空间并默认初始化
为父类对象的静态成员变量显示初始化
为父类对象的静态成员方法开辟空间
为父类对象的成员方法开辟空间
执行父类对象的静态代码块
把子类的class文件加载入内存
为子类对象的静态成员变量开辟空间并默认初始化
为子类对象的静态成员变量显示初始化
为子类对象的静态成员方法开辟空间
为子类对象的成员方法开辟空间
执行子类对象的静态代码块
创建
为Object类的对象开辟空间
为父类对象开辟空间
为父类对象的普通成员变量开辟空间并默认初始华
为父类的普通成员变量显示初始化
为子类对象的this super开辟空间
执行父类对象的构造代码块
执行父类对象的构造方法
为子类对象开辟空间
为子类对象的普通成员变量开辟空间并默认初始化
为子类对象的普通成员变量显示初始化
为子类对象的this super开辟空间
执行子类对象的构造代码块
执行子类对象的构造方法
使用
class Fu{
int a=10;
public void test1(){
System.out.println("父类的test1方法");
}
}
class Zi extends Fu{
int b=20;
public void test2(){
System.out.println("子类的test2方法");
}
}
public class ObjectClassDmoe4{
public static void main(String[] args){
Zi zi=new Zi();
}
}
一,Object类的概述
1,每个类都有直接或间接的继承了Object类。
Object类 是类层次结构的跟类,每个类都使用Object作为超类。
所有对象(包括数组)都实现这个类的方法。
我们自定义的任意类的对象都是默认就拥有Object类的所有的方法。
2,方法分类
hashCode() 返回对象的哈希码值
equals(Object obj) 指示其它某个对象是否与此对象“相等”。
toString() 返回该对象的字符串表示
finalize() 当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此法 (熟悉 面试题)。
getClass() 返回此Object的运行时类 (重要 在后面的反射课程讲解)
clone() 创建并返回此对象的一个副本 (了解)
wait notifl notifyAll 线程交互方法(重要 线程课程讲解)
这个三个方法都属于Object类的,不属于线程类的。
二,hashCode方法
1,API中的介绍
返回该对象的哈希码值,就是这个方法能根据当前对象返回一个值。
2,特点:
A,在java应用程序执行期间,在对同一个对象多次调用hashCode方法时,必须一致的返回相同的整数。
B,从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
不同的程序执行过程,调用hashCode可以返回不同的数值。
C,如果根据equals(Object)方法,两个对象时相等的,那么对这两个对象中的每个对象调用hashCode。方法
必须生成相同的整数。
D,hashCode如果相等,则可以判定两个对象相等(hashCode类似对象的身份证),常用于判断是否同一个对象。
class T1{
}
public class ObjectClassDemo1{
public static void main(String[] args){
//测试同一次执行过程中,调用同一个对象的多次hashCode值,必须一样。
T1 tt=new T1( );
//多次调用 tt 对象的hashCode方法
System.out.println( tt.hashCode( ) );
System.out.println( tt.hashCode( ) );
//以上的输出是在一次执行过程中,对比对象调用多次hashCode方法的返回值是一样的。
//不同的程序执行过程中,hashCode值可以不同
T1 tt1 = new T1( );
System.out.println( tt1 . hashCode( ) );
//常用于判断是否同一个对象
T1 tt1 = new T1( );
T1 tt2 = new T1( );
//输出tt1和tt2的hashCode值
System.out.println( tt1 . hashCode( ) );
System.out.println( tt2 . hashCode( ) );
//由以上输出可以看出不同对象的hashCode值是不同的
T1 tt3 = tt2;//索引值复制
System.out.println( tt2 . hashCode( ) );
System.out.println( tt3 . hashCode( ) );
}
}
三,equals方法
1,== 比较运算符 判断操作
==既可以用于比较基本数据类型,也可以用于比较引用数据类型。
基本数据类型中是用于判定两个变量的具体数值是否相等。
引用数据类型中比较的是两个变量是否指向内存中的同一个地址值。
==对于引用数据类型的比较,用于比较的是地址。
2,equals
equals只能用于引用数据类型的比较判等。
在Object类中的equals方法实际上底层就是使用==进行比较的,就是比较的两个对象的地址是否相等。
3,通常的equals使用方式
eg:
如果在同一个班里,没有相同名称的同学,我就可以认为如果你给我两个学生对象,如果年龄和姓名一样,我就认为是同一个人。
4,equals总结
A,原有的Object类中的equals方法是比较地址值(底层是使用==进行比较)
B,往往在真正做系统时,根据需求重写equals方法。
C,重写equals方法通常和hashCode有关联(两个都需要重写)
hashCode可以认为是对象的身份证号码
equals可以认为是对象的描述信息进行比较
因为身份证号不同,可能名称相同;所以可能会出现hashCode不等,equals相等的情况。
推荐是如果需要重写hashCode或者equals方法的任何一个,就重写另外一个。
D,重写的关键是要根据项目需求找到判等规则。
class Student{
private String name;
private int age;
public Student(){
}
public Student(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
//重写Object类中的hashCode方法和equals方法
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Student other = (Student) obj;
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
}
class T2{ }
public class ObjectClassDemo2{
public static void main(String[] args){
//创建T2类的对象
T2 t1=new T2();
T2 t2=new T2();
//两个对象使用==进行比较
System.out.println(t1==t2);//false
System.out.println(t2==t2);//true
//两个对象使用equals方法比较
System.out.println(t1 . equals( t2 ));//false
System.out.println(t1 . equals( t1 ));//true
//创建两个学生类对象,同名称同年龄
Student st1 =new Student("aaa",20);
Student st2 =new Student("aaa",20);
//按照业务需求,这个两个对象时同一个人,但是方法没有重写。结果会出现问题
System.out.println(t1 . equals( t2 ));//false 没有方法重写
//hashCode和equals方法重写之后
System.out.println(t1 . equals( t2 ));//true
}
}
四,toString方法
1,以字符串的形式返回对象的描述信息。
对象的描述信息就是指对象的外部特征即属性。
2,Object类中的toString方法默认的输出
getClass().getName()+"@"+Integer.toHexString(hashCode())
getClass().getName():类的全名称 带有包名次的类名次
Integer.toHexString(hashCode()):返回对象的hashCode值的十六进制字符串表示形式。
3,toString方法在实际系统中的使用方式
往往会在子类中重写这个toString方法,以输出具有实际意义的字符串。
Object类中的toString方法输出的信息对于实际业务来说没有任何意义,所以
通常都会重写toString方法。
4,直接输出对象,就是调用此对象的toString方法。
class T3{ }
class Teacher{
private String name;
private int age;
public Teacher(){
}
public Teachr(String name,int age){
this.name=name;
this.age=age;
}
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.age=age;
}
public int getAge(){
return age;
}
//重写的toString方法
public String toString() {
return "Teacher [name=" + name + ", age=" + age + "]";
}
}
public class ObjectClassDemo3{
public static void main(String[] args){
T3 tt=new T3();
System.out.println(tt.toString());//类和包的全名称,还有十六进制的字符串形式
Teacher teacher=new Teacher( );
System.out.println( teacher.toString() );
//重写之前的输出 Object . Teacher@dc5869
//重写toString方法之后的输出
Teacher[name=null; age=0]
}
}
五,finalize方法:
1,它是对象的生命周期方法。
对象被创建之后立即执行的方法: 构造方法
对象在销毁之前立即执行的方法: finalize方法
2,final finally finalize有什么区别?
final:是修饰符,表示最终。
可以修饰类、成员变量、成员方法、局部变量。
fianlly:在异常机制中,必须被执行的代码。
finalize:是Object类的一个方法,在对象被回收之前会被自动调用执行。
六,一个对象的创建步骤:
加载
在第一次使用类之前,需要把class加载入内存
把Object类加载入内存
把父类class文件加载入内存
为父类对象的静态成员变量开辟空间并默认初始化
为父类对象的静态成员变量显示初始化
为父类对象的静态成员方法开辟空间
为父类对象的成员方法开辟空间
执行父类对象的静态代码块
把子类的class文件加载入内存
为子类对象的静态成员变量开辟空间并默认初始化
为子类对象的静态成员变量显示初始化
为子类对象的静态成员方法开辟空间
为子类对象的成员方法开辟空间
执行子类对象的静态代码块
创建
为Object类的对象开辟空间
为父类对象开辟空间
为父类对象的普通成员变量开辟空间并默认初始华
为父类的普通成员变量显示初始化
为子类对象的this super开辟空间
执行父类对象的构造代码块
执行父类对象的构造方法
为子类对象开辟空间
为子类对象的普通成员变量开辟空间并默认初始化
为子类对象的普通成员变量显示初始化
为子类对象的this super开辟空间
执行子类对象的构造代码块
执行子类对象的构造方法
使用
class Fu{
int a=10;
public void test1(){
System.out.println("父类的test1方法");
}
}
class Zi extends Fu{
int b=20;
public void test2(){
System.out.println("子类的test2方法");
}
}
public class ObjectClassDmoe4{
public static void main(String[] args){
Zi zi=new Zi();
}
}