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

1、hashCode方法

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

 @Test
public void testHashCode() {
Student student = new Student(); for (int i = 0; i < 3; i++) {
System.out.println(student.hashCode());
}
}
 249123537
249123537
249123537

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

  1. 在Java应用程序执行期间,在对同一对象多次调用hashCode方法时,必须一致地返回相同的整数,前提是将对象进行equals比较时所用的信息没有被修改。从某一应用程序的一次执行到同一应用程序的另一次执行,该整数无需保持一致。
  2. 如果根据equals(Object)方法,两个对象是相等的,那么对这两个对象中的每个对象调用hashCode方法都必须生成相同的整数结果。
  3. 如果根据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方法与==运算符是一样的

 public boolean equals(Object obj) {
return (this == obj);
}

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

 public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

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

3、getClass方法

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

 @Test
public void testGetClass() {
Student student = new Student();
System.out.println(student.getClass());
}
class com.java.test.Student

4、toString方法

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

 public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

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

 @Test
public void testToString() {
Student student = new Student();
System.out.println(student);
System.out.println(student.toString());
System.out.println(student.getClass().getName() + "@" + Integer.toHexString(student.hashCode()));
}
 com.java.test.Student@cb5efc8
com.java.test.Student@cb5efc8
com.java.test.Student@cb5efc8

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

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

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

5、clone方法

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

 @Test
public void testClone() throws CloneNotSupportedException {
Student student1 = new Student("John", 23);
Student student2 = (Student) student1.clone();
System.out.println(student1);
System.out.println(student2);
System.out.println("改变student1的属性值后:");
student1.setName("Jack");
student1.setAge(22);
System.out.println(student1);
System.out.println(student2);
}
 Student [name=John, age=23]
Student [name=John, age=23]
改变student1的属性值后:
Student [name=Jack, age=22]
Student [name=John, age=23]

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

6、finalize方法

 protected void finalize() throws Throwable { }

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

附完整代码:

 package com.java.test;

 import org.junit.Test;

 public class StudentTest {

     @Test
public void testHashCode() {
Student student = new Student(); for (int i = 0; i < 3; i++) {
System.out.println(student.hashCode());
}
} @Test
public void testGetClass() {
Student student = new Student();
System.out.println(student.getClass());
} @Test
public void testToString() {
Student student = new Student();
System.out.println(student);
System.out.println(student.toString());
System.out.println(student.getClass().getName() + "@" + Integer.toHexString(student.hashCode()));
} @Test
public void testClone() throws CloneNotSupportedException {
Student student1 = new Student("John", 23);
Student student2 = (Student) student1.clone();
System.out.println(student1);
System.out.println(student2);
System.out.println("改变student1的属性值后:");
student1.setName("Jack");
student1.setAge(22);
System.out.println(student1);
System.out.println(student2);
}
}
 package com.java.test;

 public class Student implements Cloneable {
private String name;
private int age; public Student() {
super();
} 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;
} @Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
} }

Java基础之Object类的更多相关文章

  1. Java基础:Object类中的equals与hashCode方法

    前言 这个系列的文章主要用来记录我在学习和复习Java基础知识的过程中遇到的一些有趣好玩的知识点,希望大家也喜欢. 一切皆对象   对于软件工程来说面向对象编程有一套完整的解决方案:OOA.OOD.O ...

  2. 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解(转载)

    java中的hashcode.equals和toString方法都是基类Object的方法. 首先说说toString方法,简单的总结了下API说明就是:返回该对象的字符串表示,信息应该是简明但易于读 ...

  3. Java基础教程——Object类

    Object类 Object类是Java所有类类型的父类(或者说祖先类更合适) <Thinking in Java(Java编程思想)>的第一章名字就叫"everything i ...

  4. Java基础-DButils工具类(QueryRunner)详解

    Java基础-DButils工具类(QueryRunner)详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 如果只使用JDBC进行开发,我们会发现冗余代码过多,为了简化JDBC ...

  5. Java基础之File类的使用

    Java基础之File类的使用 1.File类的构造方法和常用方法 2.对File中listFile(FileNameFilter name)学习 3.与File文件类相关的实现 File类的构造方法 ...

  6. Java学习笔记二十四:Java中的Object类

    Java中的Object类 一:什么是Object类: Object类是所有类的父类,相当于所有类的老祖宗,如果一个类没有使用extends关键字明确标识继承另外一个类,那么这个类默认继承Object ...

  7. Java常见对象Object类中的个别方法

    Java常见对象Object类 public int hashCode() : 返回该对象的哈希码值. 注意:哈希值是根据哈希算法计算出来的一个值,这个值和地址值有关,但是不是实际地址值.你可以理解成 ...

  8. Java基础(43):Java中的Object类与其方法(转)

    Object类 java.lang.Object java.lang包在使用的时候无需显示导入,编译时由编译器自动导入. Object类是类层次结构的根,Java中所有的类从根本上都继承自这个类. O ...

  9. 【Java基础】常用类

    常用类 字符串相关的类 String类:代表字符串,使用一对 "" 引起来表示. public final class String implements java.io.Seri ...

随机推荐

  1. 【自动化专题】借助firefox插件定位web元素小技巧

    浏览器:firefox 插件:firebug.firepath.firefinder 安装插件---已安装的请跳过 1.安装firefox浏览器 2.打开firefox-附加组件(找不到入口的问度娘) ...

  2. Socket编程入门

      socket基本知识 网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket. 建立网络通信连接至少要一对端口号(socket).socket本质是编程接口(AP ...

  3. ovs-vsctl 命令详解

    Open vSwitch中有多个命令,分别有不同的作用,大致如下: ovs-vsctl用于控制ovs db ovs-ofctl用于管理OpenFlow switch 的 flow ovs-dpctl用 ...

  4. redis 数据备份持久化方案

    本文链接:http://www.cnblogs.com/zhenghongxin/p/9050219.html 使用两种备份方案 备份方案选择RDB和AOF同时进行备份,必须打开AOF的持久化机制,除 ...

  5. jzoj2941

    我們可以暴力枚舉每一個人分幾個糖果,再暴力統計答案即可 每次遞歸下去可以從1-n號人,決定選多少個糖果再遞歸 #include<bits/stdc++.h> using namespace ...

  6. Android逆向系列文章— Android基础逆向(6)

    本文作者:HAI_ 0×00 前言 不知所以然,请看 Android逆向-Android基础逆向(1) Android逆向-Android基础逆向(2) Android逆向-Android基础逆向(2 ...

  7. 频繁项集挖掘之Aprior和FPGrowth算法

    频繁项集挖掘的应用多出现于购物篮分析,现介绍两种频繁项集的挖掘算法Aprior和FPGrowth,用以发现购物篮中出现频率较高的购物组合. 基础知识 项:“属性-值”对.比如啤酒2罐.  项集:项的集 ...

  8. SAX,功能强大的 API

    https://www.ibm.com/developerworks/cn/xml/x-saxapi/ SAX,功能强大的 API 在摘自 XML by Example 的本篇预览中比较了 DOM 和 ...

  9. Centos7安装Chacha20加密算法 (验证成功)

    Centos7安装Chacha20加密算法 (验证成功) 有些程序会使用Chacha20加密算法,如果Centos7系统报错Exception: libsodium not found,则缺乏M2Cr ...

  10. 使用win10自带邮件应用发送文件

    之前的电脑装过邮件客户端,想发送文件给别人时,只需要“右键文件——发送到邮件”,就能把文件作为附件发送给对方.新电脑win10系统自带邮件客户端,所以就想直接用.但是右键发送到邮件没有关联上,用不了. ...