java day022 Object类
1.什么是Object类
Object类是所有类的基类,所有类都默认的隐式继承了Object类。
package com.qfedu.study.testobject;
class A {
int i;
public A() {
}
public A(int i) {
this.i = i;
}
}
public class TestObject {
public static void main(String[] args) {
A a = new A(1);
System.out.println(a.toString());
}
}
/*
*输出结果:
* com.qfedu.study.testobject.A@15db9742
*/
这里面的a.toString()就是a对象调用了基类Object中的toString方法。
2.toString方法重写
原来Object类中的toString方法只是返回对象的包名.类名@所在内存首地址,这样无法满足我们的需求,所以我们需要在子类中对toString方法进行重写,改成返回对象的属性信息。
package com.qfedu.study.testobject;
class A {
int i;
public A() {
}
public A(int i) {
this.i = i;
}
@Override
public String toString() {
return "A [i=" + i + "]";
}
}
public class TestObject {
public static void main(String[] args) {
A a = new A(1);
System.out.println(a.toString());
}
}
/*
*输出结果:
* A [i=1]
*/
注意:这里A类的toString方法可以依靠工具自动生成。
3.equals方法重写
原本Object类中的equals方法是比较对象之间的内存首地址。
package com.qfedu.study.testobject;
class A {
int i;
public A() {
}
public A(int i) {
this.i = i;
}
@Override
public String toString() {
return "A [i=" + i + "]";
}
}
public class TestObject {
public static void main(String[] args) {
A a1 = new A();
A a2 = new A();
System.out.println(a1.equals(a2));
}
}
/*
*输出结果:
* false
*/
但是有时候这也不满足我们的需求,尤其是在面临两个对象的内部属性值相同时,所以我们可以重写equals方法,变成比较两个对象的内部属性是否相同。
package com.qfedu.study.testobject;
class A {
int i;
int j;
String k;
public A() {
}
public A(int i, int j, String k) {
this.i = i;
this.j = j;
this.k = k;
}
@Override
public String toString() {
return "A [i=" + i + "]";
}
@Override
public boolean equals(Object obj) {
//先比较obj与当前对象首地址,如果都指向同一个对象,则直接返回true
if (this == obj) {
return true;
}
//如果不是同一个地址,再看传入的obj对象是不是属于A类,如果不是返回false
if (!(obj instanceof A)) {
return false;
}
//如果是A类,接着就进行内部属性的比较
//若想调用obj保存的A类对象的成员方法与成员属性,首先要将Object类引用强转为A类引用
A a = (A)obj;
//注意:这里的this.k.equals方法是字符串类中的equals方法,是用来比较字符串的
return this.i == a.i && this.j == a.j && this.k.equals(a.k);
}
}
public class TestObject {
public static void main(String[] args) {
/*
*输出结果:
* false
*/
//可以看到a1与a2的内部属性完全相同,可是因为首地址不同,导致equals方法返回的是false
//所以我们可以重写equals方法
A a1 = new A(1, 2, "哈哈");
A a2 = new A(1, 2, "哈哈");
System.out.println(a1.equals(a2));
/**
* 输出结果:
* true
*/
A a3 = new A(1, 2, "哈哈");
A a4 = new A(1, 2, "哈哈");
System.out.println(a3.equals(a4));
}
}
3.hashCode方法重写
在原来的Object类中hashCode方法是返回对象地址的十进制数值,但是我们在重写equals方法后,规范要求两个对象如果相同的话,hashCode的值也必须相同,所以我们也必须重写hashCode方法。
-
若对象中含有唯一的int类型标识符,可以直接返回该标识符
-
若没有唯一标识符,或者int类型变量则采用Objects工具类提供的方法
格式
@Override public int hashCode() { return Objects.hash(成员变量名); }
package com.qfedu.study.testobject;
import java.util.Objects;
class A {
private int i;
private int j;
private String k;
public A() {
}
public A(int i, int j, String k) {
this.i = i;
this.j = j;
this.k = k;
}
public int getI() {
return i;
}
public void setI(int i) {
this.i = i;
}
public int getJ() {
return j;
}
public void setJ(int j) {
this.j = j;
}
public String getK() {
return k;
}
public void setK(String k) {
this.k = k;
}
@Override
public String toString() {
return "A [i=" + i + "]";
}
@Override
public boolean equals(Object obj) {
//先比较obj与当前对象首地址,如果都指向同一个对象,则直接返回true
if (this == obj) {
return true;
}
//如果不是同一个地址,再看传入的obj所保存的首地址对象是不是属于A类,如果不是返回false
if (!(obj instanceof A)) {
return false;
}
//如果是A类,接着就进行内部属性的比较
//若想调用obj保存的A类对象的成员方法与成员属性,首先要将Object类引用强转为A类引用
A a = (A)obj;
//注意:这里的this.k.equals方法是字符串类中的equals方法,是用来比较字符串的
return this.i == a.i && this.j == a.j && this.k.equals(a.k);
}
/**
* 重写hashCode方法 保证相同对象的hashCode值相同
*/
@Override
public int hashCode() {
return Objects.hash(i, j, k);
}
}
public class TestObject {
public static void main(String[] args) {
/*
*输出结果:
* false
*/
//可以看到a1与a2的内部属性完全相同,可是因为首地址不同,导致equals方法返回的是false
//所以我们可以重写equals方法
A a1 = new A(1, 2, "哈哈");
A a2 = new A(1, 2, "哈哈");
System.out.println(a1.equals(a2));
/**
* 输出结果:
* true
*/
A a3 = new A(1, 2, "哈哈");
A a4 = new A(1, 2, "哈哈");
System.out.println(a3.equals(a4));
/**
* 输出结果:
* 725342
* 725342
*/
System.out.println(a3.hashCode());
System.out.println(a4.hashCode());
}
}