java中Object类的使用
文章目录
b站学习视频以及笔记-尚硅谷_Java零基础教程
1. java.lang.Object类的说明
- Object类是所Java类的根父类
-
如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
-
Object类中的功能(属性、方法)就具通用性。
-
属性:无
-
方法:equals() / toString() / getClass() /hashCode() / clone() / finalize()、wait() 、 notify()、notifyAll()
-
Object类只声明了一个空参的构造器
public class ObjectTest { public static void main(String[] args) { Order order = new Order(); System.out.println(order.getClass().getSuperclass()); } } class Order{ }
结果:
2. equals()方法
2.1 equals()的使用:
- 是一个方法,而非运算符
-
只能适用于引用数据类型
-
Object类中equals()的定义:
-
public boolean equals(Object obj) {
return (this == obj);
} -
说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
-
像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。
-
通常情况下,我们自定义的类如果使用equals()的话,也通常是比较两个对象的"实体内容"是否相同。那么,我们就需要对Object类中的equals()进行重写.
-
重写的原则:比较两个对象的实体内容是否相同.
-
重写案例如下:
public class Euals { Euals(String name,int age){ this.name = name; this.age = age; } private int age; private String name; public static void main(String[] args) { Euals c = new Euals("TAO",10); Euals d = new Euals("TAO",10); System.out.println(c); System.out.println(d); System.out.println(c.equals(d)); } /** * @MethodName: equals * @Description: 手动重写equals方法,比较类的实体内容是否相同 * @author Tao * @param obj * @return * @see java.lang.Object#equals(java.lang.Object) * @date 2020年11月10日 */ @Override public boolean equals(Object obj) { if (this == obj) { return true; }if(obj instanceof Euals){ //此处为何要向下转型?调用子类属性,必须向下转型。关于向下转型在我的多态性文章有。 如果不向下转型,通过obj无法调用真实对象特有的属性和方法。只有这样才能调用 Euals objAtest = (Euals) obj; //需要比较什么内容一致就写什么条件,比如我只要名字相同的话就可以省略年龄这个属性。 return this.name.equals(objAtest.name) && this.age == objAtest.age ; //当比较引用数据类型时,我们必须使用equals()方法,因为此时比较的才是实体内容,当用“==”比较时,比较的是地址。其实在这里我们用“==”也实现了,至于为什么,在后面的“==运算符”讲到。如果此处出现了自定义类型的比较时,我们也需要在那个类里面重写equals()方法,可以用自动生成实现。 } return false; } }
上述例子未进行equals方法的重写时,可以看到输出结果为false,此时比较的是两个变量的地址值。
进行重写后,可以看到输出结果为true,此时比较的就只是变量的实体内容,不再是地址值,因为实体内容都为‘’‘TAO’且age都为10,所以返回true。在开发过程中,我们会经常要将自己定义类的内容进行比较,所以需要了解怎么手动重写equals方法。
这里我用开发工具导入equals方法:
//开发工具导入的equals重写方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Euals other = (Euals) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
严格来讲,开发工具导入的重写方法肯定是更严密的。
2.2 如何重写equals()
2.2.1 手动重写举例:
class User{
String name;
int age;
//重写其equals()方法
public boolean equals(Object obj){
//如果当前对象和形参对象引用地址一样就返回true
if(obj == this){
return true;
}
//判断obj是否是User类的实例
if(obj instanceof User){
User u = (User)obj;
return this.age == u.age && this.name.equals(u.name);
}
return false;
}
}
2.2.2 开发中如何实现:自动生成的
//开发工具自动生成的equals()
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Customer other = (Customer) 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;
}
2.3 回顾 == 运算符的使用:
-
== :运算符
-
可以使用在基本数据类型变量和引用数据类型变量中
-
如果比较的是基本数据类型变量:比较两个变量保存的数据是否相等。(不一定类型要相同)
-
如果比较的是引用数据类型变量:比较两个对象的地址值是否相同,即两个引用是否指向同一个对象实体
-
补充: == 符号使用时,必须保证符号左右两边的变量类型一致。
//基本数据类型 int i = 10; int j = 10; double d = 10.0; System.out.println(i == j);//true System.out.println(i == d);//true boolean b = true; // System.out.println(i == b); char c = 10; System.out.println(i == c);//true char c1 = 'A'; char c2 = 65; System.out.println(c1 == c2);//true //引用类型: Euals tao1 = new Euals("Tom",21); Euals tao2 = new Euals("Tom",21); System.out.println(cust1 == cust2);//false String str1 = new String("atguigu"); String str2 = new String("atguigu"); System.out.println(str1 == str2);//false System.out.println("****************************"); System.out.println(tao1.equals(tao2));//false--->true这里是从Euals类从没有重写equals()方法到重写后 System.out.println(str1.equals(str2));//true Date date1 = new Date(32432525324L); Date date2 = new Date(32432525324L); System.out.println(date1.equals(date2));//true
那么为什么会出现上面的重写equals()方法时,用“==”也可以实现呢?
String e = "hahaha"; String f = "hahaha"; System.out.println(e==f);//true // 为什么上面为true,下面为false? // 此时要涉及到内存解析,上面的e和f在栈中,他们初始化的值都为‘hahaha’存放在方法区的常量池中, // 在这里有一个特点就是再定义一个变量跟已有的变量初始化值相同就会直接赋用这个初始化值,然后这个初始化值会将地址同时传给两个变量, // 所以这两个变量指的同一地址,所以地址一样,就为true。 // 所以下面的new了新的对象,地址肯定就不一样,所以为false. // 所以之前说的”==“为什么能实现是因为他初始化值的时候采用的上面的方法: // Euals c = ("TAO",10); // Euals d = ("TAO",10); // 如果改成下面这种方法就返回false了: // Euals c = new Euals(new String("TAO"),10); // Euals d = new Euals(new String("TAO"),10); // 所以重写equals方法时比较引用数据类型要用equals而不是== String gString = new String("hahaha"); String hString = new String("hahaha"); System.out.println(gString==hString);//false
3. toString()方法
3.1 toString()的使用:
-
当我们输出一个对象的引用时,实际上就是调用当前对象的toString()
-
Object类中toString()的定义:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
和equals方法一样,也要重写方法。像String、Date、File、包装类等都重写了Object类中的toString()方法。使得在调用对象的toString()时,返回"实体内容"信息。
当我们自定义类的时候,我们调用对象的toString()方法时,我们往往也希望输出的是’实体内容‘信息,这个时候我们就需要对toString()方法进行重写。
还是上个例子
toString()方法未重写时:
toString()方法重写之后:
public class Euals {
Euals(String name){
this.name = name;
}
private String name;
public static void main(String[] args) {
Euals c = new Euals("TAO");
Euals d = new Euals("TAO");
System.out.println(c);
System.out.println(d);
System.out.println(c.equals(d));
}
//重写toString方法
@Override
public String toString() {
return "Euals [name=" + name + "]";
}
public class ToStringTest {
public static void main(String[] args) {
Customer cust1 = new Customer("Tom",21);
System.out.println(cust1.toString());
//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
System.out.println(cust1);
//com.atguigu.java1.Customer@15db9742-->Customer[name = Tom,age = 21]
String str = new String("MM");
System.out.println(str);//MM
Date date = new Date(4534534534543L);
System.out.println(date.toString());//Mon Sep 11 08:55:34 GMT+08:00 2113
}
}
自定义类也可以重写toString()方法,当调用此方法时,返回对象的"实体内容"。
3.2 如何重写toString()
//手动实现
@Override
public String toString() {
return "Customer[name = " + name + ",age = " + age + "]";
}
//自动实现
@Override
public String toString() {
return "Customer [name=" + name + ", age=" + age + "]";
}
自动实现: