Object类定义:
Object类是所有类的父类,每个类都会直接或者是间接的继承Object类,因此Object类常称为超类,如果定义一个类时,没有用extends关键字显示的指定继承一个父类,那么该类就会默认继承Object类。就好比地球进化的最开始的那一个单细胞后续的生物都是直接或者间接的继承了它。
Object类是位于java.lang.包下的
Object类可以储存任意对象:
作为参数,可以接受任何对象
作为返回值,可以返回任何对象
常用方法:
一:getClass()
public final Class<?> getClass(){}
.)返回引用中储存的实际对象类型
应用:通常用于判断两个引用中实际储存对象类型是否一致(getClass方法返回值是Class类型)
例:
我们先定义一个学生的基类在这个类里定义两个变量
package TestObject.getClass;
//getClass 方法练习
public class Student {
private String name;
private int age;
public Student(){
//无参构造
}
public Student(String name,int age){
super();
this.name = name;
this.age = age;
}
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;
}
}
然后创建一个测试类调用基类创建对象进行getClass()方法的调用练习对比
package TestObject.getClass;
public class TestStudent {
public static void main(String[] args){
Student s1 = new Student();
Student s2 = new Student();
//判断s1何s2是不是同一个类型
/*因为getClass方法返回指是Class类型所有我们可以将他们赋值
给新的Class对象这样会方便后续的对比
*/
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (class1 == class2){
System.out.println("s1和s2是同一个类型");
}else{
System.out.println("s1和s2不是同一个类型");
}
}
}
运行结果:
我们进行第二次比较新创建一个老师类属性内容和学生类一样然后创建老师类对象与s1和s2进行比较:代码如下
package TestObject.getClass;
public class TestStudent {
public static void main(String[] args){
//1.练习一
Student s1 = new Student();
Student s2 = new Student();
//判断s1何s2是不是同一个类型
/*因为getClass方法返回指是Class类型所有我们可以将他们赋值
给新的Class对象这样会方便后续的对比
*/
Class class1 = s1.getClass();
Class class2 = s2.getClass();
if (class1 == class2){
System.out.println("s1和s2是同一个类型");
}else{
System.out.println("s1和s2不是同一个类型");
}
//练习二:我们在创建一个对象用这个新的对象与s2和s2进行对比
//先创建一个老师类和学生类一样的属性就可以了,然后我们来创建个老师对象进行比较
Teacher t = new Teacher();
Class class3 = t.getClass();
//进行比较(s1和t)
if (class1==class3){
System.out.println("s1和t属于同一个类型");
}else{
System.out.println("s1和t不属于同一个类型");
}
//进行比较(s2和t)
if (class2==class3){
System.out.println("s2和t属于同一个类型");
}else{
System.out.println("s2和t不属于同一个类型");
}
}
}
运行结果:
二:hashCode()方法:
public int hashCode() {}
返回值是一个哈希码值
哈希码值是根据对象的地址或字符串或数字使用hash算法计算出的int类型的数值
一般情况下相同对象返回相同的数值
例:我们重新创建一个类再在这个类里创建,之前创建的两个类的对象进行hashCode()方法测试
package TestObject.hashCode;
import TestObject.getClass.Student;
import TestObject.getClass.Teacher;
public class TestHashCode {
public static void main(String[] args){
//hashCode()方法练习
//练习一
Student s1 = new Student();
Teacher t = new Teacher();
System.out.println(s1.hashCode());
System.out.println(t.hashCode());
}
}
运行结果:
练习二:我们将s1赋值给s2看看s2的哈希值是否和s1的值一样
package TestObject.hashCode;
import TestObject.getClass.Student;
import TestObject.getClass.Teacher;
public class TestHashCode {
public static void main(String[] args){
//hashCode()方法练习
//练习一
Student s1 = new Student();
Teacher t = new Teacher();
System.out.println(s1.hashCode());
System.out.println(t.hashCode());
//练习二
Student s2 = s1;
System.out.println(s2.hashCode());
}
}
运行结果:显示为一样
为啥呢?因为s1创建的时候会在内存中开辟了一个空间,当我们进行s2等于s1的时候实际上是给s1重新套了个马甲而已,指向的内存地址还是一样的
方法三:toString()方法
public String toString(){}
该返回的对象字符串表示(表现形式)
可根据程序要求覆盖该方法,如:展示对象各个属性(Array/数组类型:里的toString()方法就是重写后的可以遍历数组中的所有元素)
例:
它的返回值是以哈希值的方式的
package TestObject;
import TestObject.getClass.Student;
public class toString {
public static void main(String[] args){
//toString方法练习
Student s = new Student();
System.out.println(s.toString());
}
}
返回值:前面是这个类所在的地址@后是这个对象的哈希值
我们进行第二次测试,测试jdkArray(数组)类型内重写的toString()方法首先先创建一个数组然后调用
import TestObject.getClass.Student;
import java.util.Arrays;
public class toString {
public static void main(String[] args){
//toString方法练习
//练习一
Student s = new Student();
System.out.println(s.toString());
//练习二
int[] a = {1,2,3,4,5,6,7,8,9};
//用Array类来调用重写的方法
System.out.println(Arrays.toString(a));
}
}
运行结果:
然后我们自己也尝试重写一下,在Student类中进行该方法的重写
重写的代码块
//尝试重写一下toString()方法
public String toString(){
return name+":"+age;
}
然后在测试类中在创建一个对象赋值上名字和年龄调用自己重写后的方法
package TestObject;
import TestObject.getClass.Student;
import java.util.Arrays;
public class toString {
public static void main(String[] args){
//toString方法练习
//练习一
Student s = new Student();
System.out.println(s.toString());
//练习二
int[] a = {1,2,3,4,5,6,7,8,9};
//用Array类来调用重写的方法
System.out.println(Arrays.toString(a));
//练习三:调用自己重写的toString()方法
Student s1 = new Student("张三", 18);
System.out.println(s1.toString());
}
}
运行结果:成功返回了名字和年龄
我们也可以使用自带的快捷键进行重写:在使用IDEA的情况下按住Alt键加上Ins键后选择toString()方法后 ,将两个属性选择就会自动生成重写后的方法
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
方法四:equals()方法
public boolean equals(Object obj){}
默认实现为(this == obj),比较两个对象地址是否相同。
可进行覆盖,比较两个对象的内容是否相同。
例:
package TestObject;
import TestObject.getClass.Student;
public class equals {
public static void main(String[] args){
//equals()方法判断两个对象(地址)是否相等
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1.equals(s2));
}
}
运行结果:(this代表s1 obj代表s2)
刚刚的不够直观我们进行第二次测试
package TestObject;
import TestObject.getClass.Student;
public class equals {
public static void main(String[] args){
//equals()方法判断两个对象(地址)是否相等
//方式一
Student s1 = new Student();
Student s2 = new Student();
System.out.println(s1.equals(s2));
//方式二
Student s3 = new Student("张三",17);
Student s4 = new Student("张三",17);
System.out.println(s3.equals(s4));
}
}
运行结果:(在这次测试中虽然我们赋值都是一样的但是这两个对象在内存中占的位置是不一样的所有是false)
之前也讲了我们这个方法是可以进行覆盖(也就是重写)的我们可以想办法让它进行内容比较而不是地址比较
equals()方法覆盖步骤:
1.比较两个引用是否指向同一个对象
2.判断obj是否为null。
3.判断两个引用指向的实际对象类型是否一致
4.强制类型转换
5.依次比较各属性是否相同
重写完毕然后进行调用比较
//equals()方法重写:比较两个对象的值
public boolean equals(Object obj){
//1.判断两个对象是否相同
if (this == obj){
return true;
}
//2.判断obj是否为null
if (obj == null){
return false;
}
//3.判断是否是同一个类
// if (this.getClass() == obj.getClass()){
//这是一种方法
// }
//instanceof关键字 判断对象是否是某种类型
//obj代表传进来的对象,Student是我们创建的当前对象的类
if (obj instanceof Student){
//4.强制类型转换
Student s = (Student)obj;
//5.比较属性
//String类型可以用equals()方法比较int类型==就可以了
if (this.name.equals(s.getName()) && this.age == s.getAge()){
return true;
}
}
return false;
}
我们还是运行刚刚赋值的两个对比
运行结果:
方法五:finalize()方法:
当对象被判定为垃圾时,有JVM(Java虚拟机)自动调用此方法,用于标记垃圾对象,进入回收队列(一般是不需要我们去调用的)。
垃圾对象:没有有效引用指向此对象时,为垃圾对象。
垃圾回收:有GC销毁垃圾对象,释放数据储存空间。
自动回收机制:JVM内存耗尽,一次性回收所有垃圾对象。
手动回收机制:使用System.gc(),通知JVM执行回收垃圾对象。(这个方法最终判断是否回收还是由系统决定的我们只是提醒它一下)
首先我们先重写一下方法由于这个方法原始情况下是没有具体返回的我们加一句输出在这个方法被调用的时候可以明显看出来
原始方法:
重写后的方法:
@Override
protected void finalize(){
System.out.println(this.name+"垃圾回收了");
}
然后进行调用:先创建几个对像
package TestObject;
import TestObject.getClass.Student;
public class finalize {
public static void main(String[] args){
//方式一
Student s1 = new Student("李四",88);
Student s2 = new Student("王五",8);
Student s3 = new Student("张三",18);
Student s4 = new Student("刘能",28);
Student s5 = new Student("杰克",38);
//提醒系统回收垃圾
System.gc();
System.out.println("回收垃圾");
}
}
运行结果:只打印了回收垃圾这句话,回收垃圾方法并没有调用
再次测试:我们将所有创建的对象变成匿名对象看一下
package TestObject;
import TestObject.getClass.Student;
public class finalize {
public static void main(String[] args){
//方式一
Student s1 = new Student("李四",88);
Student s2 = new Student("王五",8);
Student s3 = new Student("张三",18);
Student s4 = new Student("刘能",28);
Student s5 = new Student("杰克",38);
//提醒系统回收垃圾
System.gc();
System.out.println("回收垃圾");
//方式二:我们将前面的对象全部改成匿名变量看一下
new Student("李四",88);
new Student("王五",8);
new Student("张三",18);
new Student("刘能",28);
new Student("杰克",38);
//再次提醒系统回收垃圾
System.gc();
System.out.println("回收垃圾");
}
}
运行结果:运行成功(匿名对象因为是一次性使用的所以当我们提醒JVM回收的时候就会成功回收)