java object 详解_Java基础之Object类详解

类Object是类层次结构的根类。每个类都直接或者间接地继承Object类。所有对象(包括数组)都实现这个类的方法。Object类中的构造方法只有一个,并且是无参构造方法,这说明每个类中默认的无参构造方法调用的就是Object类的无参构造方法。

1、hashCode方法

hashCode方法返回给调用者此对象的哈希码(其值由一个hash函数计算得来,一般是通过将该对象的内部地址转换成一个整数)。这个方法通常用在基于hash的集合类中(像java.util.HashMap,java.until.HashSet和java.util.Hashtable)以提高性能。

1 @Test2 public voidtestHashCode() {3 Student student = newStudent();4

5 for (int i = 0; i < 3; i++) {6 System.out.println(student.hashCode());7 }8 }

1 249123537

2 249123537

3 249123537

我们可以看到运行了3次(Student类在文章最后),结果是一样的,Java中对hashCode方法有如下约定:

在Java应用程序执行期间,在对同一对象多次调用hashCode方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。

如果根据equals(Object)方法,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode方法都必须生成相同的整数结果。

如果根据equals(java.lang.Object)方法,两个对象不相等,那么对这两个对象中的任一对象上调用hashCode方法不要求一定生成不同的整数结果。但是,程序员应该意识到,为不相等的对象生成不同整数结果可以提高哈希表的性能。

上面3句话可以理解为:

两个对象相等 <=> equals相等  => hashCode相等

hasCode不相等 => equals不相等 <=> 两个对象不相等

说来说去还是不知道这个hasCode方法是用来做什么的,上面提到该方法通常用在基于hash的集合类中,以提高性能,以Set集合为例,当往集合中添加一个新的对象时,需要知道在当前集合中是否存在存在该对象,Java会先调用hasCode方法判断集合中是否有对象的哈希码值与新的对象相等,如果不相等,则添加,如果相等,则继续用equals方法判断2个对象是否相等,只有当哈希码相等时,并且equals方法返回为true时,2个对象才认为是相等的。

2、equals方法

该方法可以用来检查一个对象与调用这个equals()的这个对象是否相等。equals字面意思是相等,说到相等,我们想到==这个运算符也是用来比较相等的,那么这两个有什么区别呢,当==用于基本类型时比较的是基本类型的值是否相同,用于引用类型时,比较的是引用类型的地址是否指向同一个地方,Object中的equals方法与==运算符是一样的

1 public booleanequals(Object obj) {2 return (this ==obj);3 }

既然有了==运算符,那还需要equals方法做什么呢,通常情况下,比较2个两个对象的地址值意义不大,所以需要重写Object类中的equals方法来满足自己的需求,例如String类中的equals方法表示的是字符串的内容是否相等。

1 public booleanequals(Object anObject) {2 if (this ==anObject) {3 return true;4 }5 if (anObject instanceofString) {6 String anotherString =(String) anObject;7 int n =value.length;8 if (n ==anotherString.value.length) {9 char v1[] =value;10 char v2[] =anotherString.value;11 int i = 0;12 while (n-- != 0) {13 if (v1[i] !=v2[i])14 return false;15 i++;16 }17 return true;18 }19 }20 return false;21 }

如果重写了equals方法,则hashCode也有必要重写。

3、getClass方法

返回此 Object 的运行时类(类对象),我们知道类是对具有一组相同特征或行为的实例的抽象并进行描述,对象则是此类所描述的特征或行为的具体实例。作为类,其本身也具有某些共同的特性,如都具有类名称、由类加载器去加载,都具有包,具有父类,属性和方法等。在Java中用Class这个类来表示其他类所具有的这些特征,因此,类本身也都是属于Class类的对象。为了与平时所说的对象区分开,通常情况称之为类对象。

1 @Test2 public voidtestGetClass() {3 Student student = newStudent();4 System.out.println(student.getClass());5 }

class com.java.test.Student

4、toString方法

返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。我们看Object类中的toString方法

1 publicString toString() {2 return getClass().getName() + "@" +Integer.toHexString(hashCode());3 }

当我们使用System.out.println(object)时,内部也是通过调用toString()来实现的。

1 @Test2 public voidtestToString() {3 Student student = newStudent();4 System.out.println(student);5 System.out.println(student.toString());6 System.out.println(student.getClass().getName() + "@" +Integer.toHexString(student.hashCode()));7 }

由于这个信息一般没有什么太大作用,所以建议所有子类都重写此方法。 重写了Student类中的toString方法后

1 Student [name=null, age=0]2 Student [name=null, age=0]

这时候的信息我们就可以很容易的理解了。

5、clone方法

创建并返回此对象的一个副本。副本可以这么理解,原来有一个文档,通过Ctrl+C复制,然后Ctrl+V黏贴一个新的文档出来,这个新的文档就叫做文档的副本,你在副本上面所做的操作不会影响到原来的文档。注意在调用clone()方法时,被调用对象需要实现Cloneable接口,如果没有实现Cloneable接口,并且子类直接调用Object类的clone()方法,则会抛出CloneNotSupportedException异常。Cloneable接口是标记接口,接口本身不包含任何方法,表示实现了这个接口,就可以实现对象的复制了。

1 @Test2 public void testClone() throwsCloneNotSupportedException {3 Student student1 = new Student("John", 23);4 Student student2 =(Student) student1.clone();5 System.out.println(student1);6 System.out.println(student2);7 System.out.println("改变student1的属性值后:");8 student1.setName("Jack");9 student1.setAge(22);10 System.out.println(student1);11 System.out.println(student2);12 }

1 Student [name=John, age=23]2 Student [name=John, age=23]3 改变student1的属性值后:4 Student [name=Jack, age=22]5 Student [name=John, age=23]

从运行结果也可以看出,被调用对象student1更改了属性值后,不会影响到副本的属性值,也说明了两者在堆空间中的位置不同。

6、finalize方法

1 protected void finalize() throws Throwable { }

当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。通常情况下,这个方法一般不会用到。

附完整代码:

1 packagecom.java.test;2

3 importorg.junit.Test;4

5 public classStudentTest {6

7 @Test8 public voidtestHashCode() {9 Student student = newStudent();10

11 for (int i = 0; i < 3; i++) {12 System.out.println(student.hashCode());13 }14 }15

16 @Test17 public voidtestGetClass() {18 Student student = newStudent();19 System.out.println(student.getClass());20 }21

22 @Test23 public voidtestToString() {24 Student student = newStudent();25 System.out.println(student);26 System.out.println(student.toString());27 System.out.println(student.getClass().getName() + "@" +Integer.toHexString(student.hashCode()));28 }29

30 @Test31 public void testClone() throwsCloneNotSupportedException {32 Student student1 = new Student("John", 23);33 Student student2 =(Student) student1.clone();34 System.out.println(student1);35 System.out.println(student2);36 System.out.println("改变student1的属性值后:");37 student1.setName("Jack");38 student1.setAge(22);39 System.out.println(student1);40 System.out.println(student2);41 }42 }

1 packagecom.java.test;2

3 public class Student implementsCloneable {4 privateString name;5 private intage;6

7 publicStudent() {8 super();9 }10

11 public Student(String name, intage) {12 super();13 this.name =name;14 this.age =age;15 }16

17 publicString getName() {18 returnname;19 }20

21 public voidsetName(String name) {22 this.name =name;23 }24

25 public intgetAge() {26 returnage;27 }28

29 public void setAge(intage) {30 this.age =age;31 }32

33 @Override34 publicString toString() {35 return "Student [name=" + name + ", age=" + age + "]";36 }37

38 @Override39 protected Object clone() throwsCloneNotSupportedException {40 return super.clone();41 }42

43 }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值