Object类的概述
- java.lang.Object
- 每一个类都使用Object作为超类,即使所有的类都是继承他
- 所有的对象(包括数组)都实现这个类的方法。
(一)从技术上面去理解
(1)所有的类都继承他
如果一个类没有显示声明它的父类,那么他的父类就是Object
(2)说明所有的类,所有的对象都拥有Object类中的方法
(3)每一个类的构造器,都会追踪到Object类中的无参构造
(二)从多态
(1)Object的变量(包括形参)可以接受任意类型的对象;多态
(2)Object的数组,可以存储任意类型的数组
数组也是应用数据类型,所以数组也有Object类中的方法。
public class TestObject {
public TestObject() {
super();//调用的是Object的无参构造器
}
public static void main(String[] args) {
TestObject t = new TestObject();
//Object的变量可以接受任意类型的对象
Object obj = "hello";
Object obj1 = new TestObject();
//Object的数组,可以存储任意类型的数组
Object[] arr = new TestObject[3];
arr[0] = "hello";
arr[1] = 12;
arr[2] = new TestObject();
//所有的对象(包括数组)都实现Object的方法
int[] nums = new int[5];
//nums是一个对象,类型是int[]
}
public void show(Object obj) {
}
}
Object部分方法的介绍
Object 的方法
(1)Class getClass() 这个Class是一个类型 ;返回Object的运行时类型
(2)String toString() 建议所有的子类都重写这个方法
- 记住:
- a 当你打印一个对象时默认调用这个对象的toString()方法
- b 当用一个对象与字符串进行拼接操作的时候也会自动的调用toString()方法
(3)双胞胎
-
int hashCode() 返回该对象的哈希吗值,支持此方法是为了提高哈希表的性能
前期是:知道他是把对象的信息,通过某种算法计算出来的int值。
设计出来的目的是,理想状态下,希望每一个对象都有一个唯一的hash码,但是现实中可能两个不同的对象但是他们的hash码是相同的。问题? (1)如果两个对象的hash码不一样能不能推导出两个对象是不一样的。 可以 (2)如果两个对象的hash码是一样的能不能推导出两个对象是相同的对象呢? 不可以的 (3)如果两个对象相同能否推出他们的hash码一样 可以的
-
boolean equals(Object obj) 指示其他的对象是否与此对象“相等”
(1)如果一个类没有重写Object的equals方法,那么效果和“==”是一样的,比较的是两个对象的地址
(2) 如果这个类不想调用equals来比较地址,而是比较属性的内容,那么需要“重写”这个方法如果不用IDE工具生成的equals方法,那么你可以自己写重写,要遵循以下几个原则。 (1)自反性: x.equals(x)自己与自己一定是相同的 (2)对称性 : x.equals(y)是true y.equals(x)也要是true (3)传递性: x.equals(y)是true y.equals(z)是true ----> x.equals(z)也是true (4)一致性:如果参与equals比较的的属性值都没有修改,那么前后两次调用应该相同 (5)对于任何非空引用值x,x.equals(null)都应该返回false
(4)protected void finalize() 当垃圾回收器确定不存在该对象更多引用时,由对象的垃圾回收器调用此方法。
比喻为:对象被回收之前,临终时的遗言。
实际上这个方法用于彻底释放资源功能
public class TestObjectMethod {
public static void main(String[] args) {
/*
Object obj = "hellow"; //"hello"是一个字符串
//obj这个对象的运行时类型:class java.lang.String
System.out.println(obj.getClass());//class java.lang.String
*/
TestObjectMethod t = new TestObjectMethod();
System.out.println(t);//com.atguigu.object.TestObjectMethod@424c0bc4
System.out.println(t.hashCode());//1112280004(十进制) 424c0bc4(十六进制)
String str = "对象的信息";
String str1 = str + t;
System.out.println(str1);
String str2 = str + t.toString();//这样写是等价的。
System.out.println(str2);
Student stu = new Student("张三",23,89);
System.out.println(stu);//Student [name=张三, age=23, score=89]
//hash 码和对象之间的关系演示
//对象不相同,但是他们的hash码是相同的。
String str11 = "BB";
String str21 = "Aa";
System.out.println(str11.hashCode());//2112
System.out.println(str21.hashCode());//2112
// boolean equals(Object obj) 指示其他的对象是否与此对象“相等”
Student stu1 = new Student("张三",23,89);
Student stu2 = new Student("张三",23,89);
/*
没有在学生类中重写equals方法所以等同于“==”都是直接比较两个对象的地址值。
System.out.println(stu1.equals(stu2));//false
System.out.println(stu1 == stu2);// false 默认比较的是两个对象的地址
*/
System.out.println(stu1.equals(stu2));//true
System.out.println(stu1 == stu2);// false 默认比较的是两个对象的地址
Scanner input = new Scanner(System.in);
System.out.println("请输入是否愿意:");
String result = input.next();
if("愿意".equals(result)) {
//String 类型重写了Object类中的equals方法。
System.out.println("太好了");
}
}
}
class Student{
private String name;
private int age;
private int score;
public Student() {
super();
}
public Student(String name, int age, int score) {
super();
this.name = name;
this.age = age;
this.score = score;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getScore() {
return score;
}
public void setScore(int score) {
this.score = score;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + ", score=" + score + "]";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + age;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + score;
return result;
}
@Override
public boolean equals(Object obj) {
//this在这个方法中代表当前的对象,调用这个方法的对象,这里代表stu1
//obj是形参,他代表实参的对象,实参对象是stu2,实参被向上转型
if (this == obj)//比较stu1和stu2的地址,如果相同,直接返回ture
return true;
if (obj == null)//如果obj是null,即stu2是null,直接返回false,因为this对象可以调用equals方法说明一定不是null,否则就是空指针异常了
return false;
//getClass();省略了this.getClass(),得到的是stu1的运行时类型
//obj.getClass();得到的是stu2的运行时类型
if (getClass() != obj.getClass())//如果stu1和stu2是不同的类型,就直接返回false
return false;
//为什么这里不需要instanceof判断
//因为上面if (getClass() != obj.getClass())保证了他们两个都是Student,因为如果stu2不是Student,上面就直接返回来false
//this(stu1)一定是Student类型,如果不是Student就要调用别的类中的equals方法
Student other = (Student) obj;//向下转型,这里向下转型是为了调用obj对象的属性值
if (age != other.age)//如果年龄不同就直接返回false
return false;
if (name == null) {//分为两种情况,首先是name为null的情况
if (other.name != null)
return false;
} else if (!name.equals(other.name))//name不是空因为是字符串类型所以所以需要用equals来判断是否相等
return false;
if (score != other.score)
return false;
return true;
}
}