Object
类是JDK类库的根类Object
。就算没有直接继承,最终也会间接继承。protected Object clone()
// 负责对象克隆的。int hashCode()
// 获取对象哈希值的一个方法。boolean equals(Object obj)
// 判断两个对象是否相等String toString()
// 将对象转换成字符串形式protected void finalize()
// 垃圾回收器负责调用的方法源代码
public String toString(){
return this.getClass().getName + Integer.toHexString(hashCode());
}
源代码上toString()
方法的默认实现是:类名@对象的内存地址转换为十六进制的形式。
toString()
方法的作用
toString()
方法的设计目的是:通过调用这个方法可以将一个“Java对象”转换成“字符串表示形式”其实SUN公司开发Java语言的时候,建议所有的子类都去重写toString()
方法。toString()
方法应该是一个简洁的、详实的、易阅读的。以后所有类的toString()
方法是需要重写的。重写规则,越简单越明了就好。
public class Test01 {
public static void main(String[] args) {
MyTime t1 = new MyTime(2020,7,2);
String s1 = t1.toString();
//MyTime类重写toString()方法之前
//System.out.println(s1);//MyTime@75412c2f
//MyTime类重写toString()方法之后
System.out.println(s1);//2020年7月2日
//输出引用的时候会自动调用该引用的toString()方法。
System.out.println(t1);//2020年7月2日
}
}
class MyTime {
int year;
int month;
int day;
public MyTime() {
}
public MyTime(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//重写toString()方法
//重写的越简洁越好,可读性越强越好
public String toString() {
return this.year + "年" + this.month + "月" + this.day + "日";
}
}
System.out.println(引用);
这里会自动调用“引用”的toString()方法。
MyTime t1 = new MyTime(2020,7,2);
String s1 = t1.toString();
System.out.println(s1);//2020年7月2日
//输出引用的时候会自动调用该引用的toString()方法。
System.out.println(t1);//2020年7月2日
equals()
方法的源代码
public boolean equals(Object obj){
return (this = obj);
}
以上是这个方法的默认实现。在Object类中的equals()方法当中,默认采用的是“==”判断两个Java对象是否相等。
SUN公司设计equals的目的是什么?
equals()
方法来判断两个对象是否相等。equals()
方法是判断两个对象是否相等的。Object
类给的这个默认方法的equals()
方法不够用。在Object类中的equals()方法当中,默认采用的是==
判断两个Java对象是否相等。而==
判断的是两个Java对象的内存地址,我们应该判断两个Java对象的内容是否相等,所以老祖宗的equals()方法不够用。
判断两个Java对象是否相等,不能使==
,因为==
比较的是两个对象的内存地址。
// 判断两个基本数据类型的数据是否相等直接使用“==”
int a = 100;
int b = 100;
// 这个“==”是判断a中保存的100和b中保存的100是否相等
System.out.println(a == b);
// 创建一个日期对象:2020年7月2日
MyTime t1 = new MyTime(2020, 7, 2);
// 创建一个新的日期对象:2020年7月2日
MyTime t2 = new MyTime(2020, 7, 2);
// 这里的“==”判断的是:t1中保存的对象内存地址和t2中保存的对象内存地址是否相等
System.out.println(t1 == t2);
重写equals()方法
public class Test01 {
public static void main(String[] args) {
// 创建一个日期对象:2020年7月2日
MyTime t1 = new MyTime(2020, 7, 2);
// 创建一个新的日期对象:2020年7月2日
MyTime t2 = new MyTime(2020, 7, 2);
//重写Object的equals()方法之前(比较的是对象的内存地址)
/*boolean flag = t1.equals(t2);
System.out.println(flag);*/
//重写Object类的equals()方法之后(比较的是内容)
boolean flag = t1.equals(t2);
System.out.println(flag);
}
}
class MyTime {
int year;
int month;
int day;
public MyTime() {
}
public MyTime(int year, int month, int day) {
this.year = year;
this.month = month;
this.day = day;
}
//默认的equals()方法
/*public boolean equals(Object obj){
return (this = obj);
}*/
//重写Object的equals()方法
public boolean equals(Object obj) {
// 获取第一个日期的时间
int year1 = this.year;
int month1 = this.month;
int day1 = this.day;
// 获取第二是日期的时间
if (obj instanceof MyTime) {
MyTime t = (MyTime) obj;
int year2 = t.year;
int month2 = this.month;
int day2 = this.day;
if(year1==year2 && month1==month2 && day1==day2){
return true;
}
}
//程序能执行到此处说明日期不相等
return false;
}
}
//改良equals()方法
public boolean equals(Object obj){
//如果obj是空的,直接返回false
if(obj==null){
return false;
}
//如果obj不是一个MyTime,就没必要比较了,直接返回false
if(!(obj instanceof MyTime)){
return false;
}
//如果this和obj保存的内存地址相同,就没必要比较了,直接返回true
//内存地址相同的时候指向的堆内存的对象肯定是同一个
if(this==obj){
return true;
}
//程序执行到此处说明,obj不是null,obj是MyTime类型
MyTime t= (MyTime)obj;
if(this.year==t.year && this.month==t.month && this.day==t.day){
return true;
}
//程序能到此返回false
return false;
}
终极改良
//终极改良
public boolean equals(Object obj) {
//如果obj是空的,或者obj不是一个MyTime,就没不必要比较了,直接返回false
if (obj == null || !(obj instanceof MyTime)) {
return false;
}
//如果this和obj保存的内存地址相同,就没必要比较了,直接返回true
//内存地址相同的时候指向的堆内存的对象肯定是同一个
if (this == obj) {
return true;
}
//程序执行到此处说明,obj不是null,obj是MyTime类型
MyTime t = (MyTime) obj;
return this.year == t.year && this.month == t.month && this.day == t.day;
}
String对象比较的时候必须使用equals()
方法
/String对象比较的时候必须使用equals()方法
public class Test02 {
public static void main(String[] args) {
Student s1 = new Student(11, "上元中学");
Student s2 = new Student(11, "上元中学");
System.out.println(s1 == s2);//false
System.out.println(s1.equals(s2));//true
}
}
class Student {
int no;//学号
String school;//所在学校
public Student() {
}
public Student(int no, String school) {
this.no = no;
this.school = school;
}
//重写toString()方法
public String toString() {
return "学号" + no + ",所在学校名称" + school;
}
// 重写equals()方法
// 需求:当一个学生的学号相等,并且学校相同时,表示同一个学生
// equals方法的编写模式是固定的。
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof Student)) return false;
if (this == obj) return true;
Student s = (Student) obj;
return this.no == s.no && this.school.equals(s.school);
}
}
equals()
方法的重写要彻底。
//equals()方法的重写要彻底。
public class Test02 {
public static void main(String[] args) {
User u1 = new User("xiaoqiang", new Address("南京", "江宁区", "上元大街"));
User u2 = new User("xiaoqiang", new Address("南京", "江宁区", "上元大街"));
System.out.println(u1.equals(u2)); //true
}
}
class User {
String name;//用户名
Address addr;//用户的住址
public User() {
}
public User(String name, Address addr) {
this.name = name;
this.addr = addr;
}
// 重写equals()方法
// 重写规则:当一个用户的用户名和用户的住址都相同时,表示同一个用户
// 这个equals判断的是User对象和User对象是否相等。
public boolean equals(Object obj) {
// 用户名和用户名相同,地址和地址相同时,认定是同一个用户
if (obj == null || !(obj instanceof User)) return false;
if (this == obj) return true;
User u = (User) obj;
return this.name.equals(u.name) && this.addr.equals(u.addr);
}
}
class Address {
String city;
String street;
String zipcode;
public Address() {
}
public Address(String city, String street, String zipcode) {
this.city = city;
this.street = street;
this.zipcode = zipcode;
}
// 注意这里并没有重写equals()方法
// 这里的equals()方法判断的是:Address对象和Address对象是否相等。
// 现在要重写equals()方法
public boolean equals(Object obj){
if(obj==null || !(obj instanceof Address)) return false;
if(this==obj) return true;
// 城市相同,街道相同,邮编相同,认定地址相同
Address a=(Address)obj;
return this.city.equals(a.city) && this.street.equals(a.street) && this.zipcode.equals(a.zipcode);
}
}
在Object类中的源代码:protected void finalize() throws Throwable{}
,finalize()
方法只有一个方法体,里面没有代码,而且这个方法是protected
修饰的。
这个方法不需要程序员手动调用,JVM的垃圾回收器负责手动调用这个方法。不像equals()方法和toString()方法是需要程序员手写代码调用的。finalize()方法只需要重写,重写完将来会自动有程序调用。
finalize()
方法的执行时机:当一个Java对象即将被垃圾回收器回收的时候,垃圾回收器负责调用finalize()
方法。
finalize()方法实际上是SUN公司为java程序员准备的一个时机,垃圾销毁时机,如果希望在对象销毁时机执行一段代码的话,这段代码要写到finalize()方法当中。
静态代码块在类加载时刻执行,并且只执行一次,这是SUN公司准备的一个类加载时机。finalize()方法同样也是SUN公司为程序员准备的一个时机,这个时机是垃圾回收时机。
Java中的垃圾回收器不是轻易启动的,垃圾太少,或者时间没到,种种条件下,有可能启动,也有可能不启动。
public class Test01 {
public static void main(String[] args) {
for (int i = 0; i < 1000000; i++) {
Person p = new Person();//创建对象
// 把Person对象变成垃圾
p = null;
}
}
}
//项目开发中有这样的需求:所有对象在JVM中被释放的时候,记录一下施放时间
//记录对象被释放的时间点,这个负责记录的代码写在finalize()方法中。
class Person {
// 重写finalize()方法
// Person对象被垃圾回收器回收的时候,垃圾回收器负责调用:p.finalize()
protected void finalize() throws Throwable {
System.out.println(this + "即将被销毁!");
}
}
// 有一段代码可以建议垃圾回收器启动
// 只是建议,可能不启动,也可能启动,只是启动的概率会大很多。
System.gc();//建议启动垃圾回收器
在Object中的源代码:public native int hashCode();
这个方法不是抽象方法,带有native关键字,底层调用c++程序。
hashCode()方法返回的是哈希码:实际上就是一个Java对象的内存地址,经过哈希算法,得出的一个值。所以hashCode()方法的执行结果可以等同看作一个Java对象的内存地址。
public class Test01 {
public static void main(String[] args) {
Object o = new Object();
int hashCodeValue = o.hashCode();
// 对象内存地址经过哈希算法转换成为一个数字,可以等同看作内存地址。
System.out.println(hashCodeValue);//1355531311
MyClass mc = new MyClass();
int hashCodeValue2 = mc.hashCode();
System.out.println(hashCodeValue2);//42121758
}
}
class MyClass {
}
java语言中的字符串String
重写了equals()
方法。比较两个字符串不能使用==
,必须使用equals()
方法,equals
是通用的。
public class Test01 {
public static void main(String[] args) {
//大部分情况下,采用这样的方式创建字符串对象
String s1 = "hello";
String s2 = "abc";
// 实际上String也是一个类,不属于基本数据类型
// 既然String是一个类,那么一定存在构造方法
String s3 = new String("test1");
String s4 = new String("test1");
// new了两次,创建出两个对象内存地址,s3保存的地址和s4保存的地址不同。
// == 判断的式内存地址,不是内容
System.out.println(s3 == s4);//false
// 比较两个字符串不能使用双等号,必须调用equals()方法
// String类已经重写equals()方法
System.out.println(s3.equals(s4));
}
}
String已经重写了toString()
方法
String x = new String("夜空星满");
//如果String没有重写toString()方法,输出结果:java.lang.String@十六进制的地址
//经过测试:String类已经重写了toString()方法
System.out.println(x.toString());//夜空星满
System.out.println(x);//夜空星满
==
进行判断。equals()
方法来判断是否相等.原文:https://www.cnblogs.com/yxc-160206/p/13228158.html