一、简述

  1、Object类是所有类的父类,即直接或间接的继承java.lang.Object类。省略了extends Object。

  2、方法

    (1)protected native Object clone() throws CloneNotSupportedException; //创建并返回一个对象的副本。

    (2)public String toString();  //返回一个字符串,一般需要重写。

    (3)public final native Class<?> getClass();  //返回对象在运行时的类的类型

    (4)public boolean equals(Object obj);  //用来判断调用equals对象与参数对象obj是否为同一个对象,一般需重写。

    (5)public native int hashCode(); //返回对象的哈希码,可用于哈希查找,减少equals比较的次数,一般重写equals方法后也要重写hashcode方法。

    (6)protected void finalize() throws Throwable { }; //该方法用于释放资源,无法确定该方法什么时候被调用。

    (7)public final native void wait(long timeout) throws InterruptedException; //使当前线程等待锁,直到获取锁或被中断,timeout指的是最长等待时间。

    (8)public final native void notify(); //用于随机唤醒该对象上等待的某个线程。

    (9)public final native void notifyAll(); //用于唤醒该对象上等待的所有线程。

  3、由于getClass()、notify()、notifyAll()、wait()等方法被final修饰,所以不能被重写。

二、Clone()

  1、clone()方法作用是返回一个Object对象的复制,且复制的对象是一个新的对象。

  

  2、使用clone()方法时,需要实现Cloneable接口,否则会抛出异常(CloneNotSupportedException)。

  3、分类:浅复制(Shallow Clone)与深复制(Deep Clone)

    (1)浅复制:复制后的对象的所有变量都与原有对象的值相同,且所有对其他对象的引用仍指向原来的对象。简单的讲,对于基本类型,复制的是数据,对于引用类型,复制的是数据的地址。即浅复制复制当前对象,不复制当前对象中的引用对象。

      注意一个坑:对于引用类型,复制的是数据的地址(通过地址访问对象的真实数据)。若通过地址来修改对象,那么原有对象以及复制的对象均会修改相应的值。但若是修改了地址(比如new了一个对象,则地址发生改变,而原有的对象并未发生改变),则只有被修改的对象才会发生改变。

    (2)深复制:指的是完全复制,将当前对象整体复制,并创建一个新的对象保存。即深复制复制当前对象,且复制当前对象中的引用对象。简单的讲,深复制在浅复制的基础上,将引用类型再复制一份,其中引用类型需要实现Cloneable接口(如下例中的People类实现了Cloneable接口)。

      注意一个坑:只有实现了Cloneable接口,才能调用clone()方法。

/**
* 引用类型,用于测试浅复制与深复制的差别。 若只是浅复制,不用实现Clonable接口。 若是深复制,则要实现Cloneable接口以及clone方法。
*/
class People implements Cloneable {
private String name;
private int age; public People(String name, int age) {
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 "People [name=" + name + ", age=" + age + "]";
} @Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
} /**
* 浅复制
*/
class ShallowCloneDemo implements Cloneable {
private People people;
private String sex; public ShallowCloneDemo(People people, String sex) {
this.people = people;
this.sex = sex;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public People getPeople() {
return people;
} public void setPeople(People people) {
this.people = people;
} @Override
protected Object clone() {
try {
return (ShallowCloneDemo) super.clone();
} catch (CloneNotSupportedException e) {
System.out.println("Shallow Clone Error");
return null;
}
} @Override
public String toString() {
return "ShallowCloneDemo [people=" + people + ", sex=" + sex + "]";
}
} /**
* 深复制
*/
class DeepCloneDemo implements Cloneable {
private People people;
private String sex; public DeepCloneDemo(People people, String sex) {
this.people = people;
this.sex = sex;
} public People getPeople() {
return people;
} public void setPeople(People people) {
this.people = people;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} @Override
protected Object clone() {
DeepCloneDemo obj = null;
try {
obj = (DeepCloneDemo) super.clone();// 浅复制
obj.people = (People) this.getPeople().clone();// 需要克隆引用类型
} catch (CloneNotSupportedException e) {
System.out.println("Deep Clone Error");
return null;
}
return obj;
} @Override
public String toString() {
return "DeepCloneDemo [people=" + people + ", sex=" + sex + "]";
} } /**
* 测试类,用于测试浅复制与深复制
*/
public class Test {
public static void main(String[] args) {
System.out.println("普通实例化一个ShallowCloneDemo:");
ShallowCloneDemo shallowCloneDemo1 = new ShallowCloneDemo(new People("rick", 18), "man");
System.out.println("实例化完成");
System.out.println(); System.out.println("通过clone()方法浅复制克隆一个ShallowCloneDemo:");
System.out.println("Start Shallow Cloning");
ShallowCloneDemo shallowCloneDemo2 = (ShallowCloneDemo) shallowCloneDemo1.clone();
System.out.println("Shallow Clone End");
System.out.println(); System.out.println("输出原有对象以及浅复制克隆对象的值:");
System.out.println(shallowCloneDemo1);
System.out.println(shallowCloneDemo2);
System.out.println(); System.out.println("对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:");
shallowCloneDemo1.getPeople().setName("tom");
shallowCloneDemo2.getPeople().setAge(20);
shallowCloneDemo1.setSex("woman");
System.out.println(shallowCloneDemo1);
System.out.println(shallowCloneDemo2);
System.out.println("结果显示,浅复制对象会随着原有对象一起修改。");
System.out.println("这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值");
System.out.println(); System.out.println("普通实例化一个DeepCloneDemo:");
DeepCloneDemo deepCloneDemo1 = new DeepCloneDemo(new People("rick", 18), "man");
System.out.println("实例化完成");
System.out.println(); System.out.println("通过clone()方法深复制克隆一个DeepCloneDemo:");
System.out.println("Start Deep Cloning");
DeepCloneDemo deepCloneDemo2 = (DeepCloneDemo) deepCloneDemo1.clone();
System.out.println("Deep Clone End");
System.out.println(); System.out.println("输出原有对象以及深复制克隆对象的值:");
System.out.println(deepCloneDemo1);
System.out.println(deepCloneDemo2);
System.out.println(); System.out.println("对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:");
deepCloneDemo1.getPeople().setName("tom");
deepCloneDemo2.getPeople().setAge(20);
deepCloneDemo1.setSex("woman");
System.out.println(deepCloneDemo1);
System.out.println(deepCloneDemo2);
System.out.println("结果显示,深复制时对象是独立的,互不干扰。");
System.out.println("这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值");
}
}
/*
测试结果:
普通实例化一个ShallowCloneDemo:
实例化完成 通过clone()方法浅复制克隆一个ShallowCloneDemo:
Start Shallow Cloning
Shallow Clone End 输出原有对象以及浅复制克隆对象的值:
ShallowCloneDemo [people=People [name=rick, age=18], sex=man]
ShallowCloneDemo [people=People [name=rick, age=18], sex=man] 对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:
ShallowCloneDemo [people=People [name=tom, age=20], sex=woman]
ShallowCloneDemo [people=People [name=tom, age=20], sex=man]
结果显示,浅复制对象会随着原有对象一起修改。
这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值 普通实例化一个DeepCloneDemo:
实例化完成 通过clone()方法深复制克隆一个DeepCloneDemo:
Start Deep Cloning
Deep Clone End 输出原有对象以及深复制克隆对象的值:
DeepCloneDemo [people=People [name=rick, age=18], sex=man]
DeepCloneDemo [people=People [name=rick, age=18], sex=man] 对原有对象进行修改后,输出原有对象以及浅复制克隆对象的值:
DeepCloneDemo [people=People [name=tom, age=18], sex=woman]
DeepCloneDemo [people=People [name=rick, age=20], sex=man]
结果显示,深复制时对象是独立的,互不干扰。
这里由于String类型相当于指向了一个新地址,所以只有被修改的对象改变值
*/

三、toString、getClass

  1、Object 类的 toString 方法返回一个字符串,该字符串由类名、标记符“@”和此对象哈希码的无符号十六进制表示组成。

  2、Object 类的getClass()方法返回一个对象的类名。

四、equals、hashcode

  1、Object中的equals方法是直接判断this和obj本身的值是否相等,即用来判断调用equals的对象和形参obj所引用的对象是否是同一对象(即是否占据同一个内存)。对于内容相同但内存不同的对象,返回false。需要进行重写,并重写比较规则,才能使其为true。

  2、Object的hashcode()方法用于哈希查找,可以减少在查找中使用equals的次数,重写了equals方法一般都要重写hashCode方法。

五、==和equals的区别是什么?

  1、==对于基本类型,比较的是值,对于引用类型,比较的引用变量的堆内存地址。

  2、equals未重写时等价于==,一般重写后用来比较两个对象的内容是否相等。

六、hashCode() 与 equals() 的关系?

  1、hashcode()的作用用于获取哈希码(散列码),其返回一个int整数,用于确定对象在哈希表中的索引位置。

  2、equals相同的两个对象的hashCode必定相同。

  3、hashCode相同的两个对象的equal不一定相同。

  4、equals重写时,hashcode一般需重写。hashcode默认为堆中对象产生的独特值,若未重写hashcode,那么即使两个对象指向同一个数据,hashcode值也不会相等。

  5、hashcode与equals在HashSet中的应用,当对象加入HashSet时,先由hashcode计算对象的散列值,若相等,则比较equals,若equals比较仍相等(即为相同对象),则对象不会加入到HashSet中。若equals比较不等,则将对象重新散列到其他位置。通过减少equals比较次数,可以提高执行速度。

Java基础--常用API--java.lang.Object的更多相关文章

  1. Java 基础 常用API (Object类,String类,StringBuffer类)

    Java API Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就是JDK中提供给我们使用的类,这些类将底 ...

  2. Java 基础 常用API (System类,Math类,Arrays, BigInteger,)

    基本类型包装类 基本类型包装类概述 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需要把字符串数据,根据需求转换成指定的基本数据类型,如年龄需要转换成int类 ...

  3. Java 基础 常用API ( 正则表达式,Date类,DateFormat类,Calendar类 )

    正则表达式 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符合某个 ...

  4. JAVA基础语法:java编程规范和常用数据类型(转载)

    JAVA基础语法:java编程规范和常用数据类型 摘要 本文主要介绍了最基本的java程序规则,和常用数据类型,其中侧重说了数组的一些操作. 面向java编程 java是纯面向对象语言,所有的程序都要 ...

  5. java基础--常用函数总结

    java基础--常用函数总结 2019-3-16-23:28:01-----云林原创 1.split()字符串分割函数 将一个字符串分割为子字符串,然后将结果作为字符串数组返回. 2.Math.flo ...

  6. Java基础16:Java多线程基础最全总结

    Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...

  7. 055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念

    055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念 本文知识点:数组的概念 数组的声明创建.初始化 在学习数组的声明创建.初始化前,我们可以和之 ...

  8. 039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述

    039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述 本文知识点:循环结构概述 循环结构主要内容 while 循环 do-whiile ...

  9. 020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结

    020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结 本文知识点:变量与常量 知识总结 Java中的标识符 Java中的关键字 目前常 ...

  10. 001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学

    001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学 welcome to Java World 欢迎来到Java世界 一起领略Java编程世界的奥秘与奥妙 ...

随机推荐

  1. Javascript-- jQuery动画篇(1)

    jQuery中隐藏元素的hide方法 让页面上的元素不可见,一般可以通过设置css的display为none属性.但是通过css直接修改是静态的布局,如果在代码执行的时候,一般是通过js控制元素的st ...

  2. stl_tree.h

    stl_tree.h G++ ,cygnus\cygwin-b20\include\g++\stl_tree.h 完整列表 /* * * Copyright (c) 1996,1997 * Silic ...

  3. the referenced script on this behaviour is missing!

    1.看看你脚本上挂的某个组件是不是发生了变动,比如被删除了什么的 2.最有可能的是你创建完脚本后,中途改过脚本的名字,致使脚本名字和内部的名字不统一.

  4. 使用UIVisualEffectView创建毛玻璃效果

    UIVisuaEffectView :继承自UIView,可以看成是专门用于处理毛玻璃效果的视图,只要我们将这个特殊的View添加到其他视图(eg. ImageView )上面,被该UIVisuaEf ...

  5. javascript中eval()函数使用方法

    本教程主要重介绍eval()函数的语法与使用方法,及在后面我还补充了eval()解析json数据的相关例子,希望文章能帮助到各位深入理解eval()使用方法吧.   前几天说到js中尽量不要使用eva ...

  6. POJ2513(字典树+图的连通性判断)

    //用map映射TLE,字典树就AC了#include"cstdio" #include"set" using namespace std; ; ;//26个小 ...

  7. netty支持的协议

    流经网络的数据总是具有相同的类型:字节.这些字节是如何流动的主要取决于我们所说的 网络传输--一个帮助我们抽象底层数据传输机制的概念.用户并不关心这些细节:他们只想确保他们的字节被可靠地发送和接收. ...

  8. w25q128 优化读写函数

    #include "w25qxx.h"  #include "spi.h" #include "delay.h"    #include & ...

  9. jquery 键盘事件的使用方法详解

    转自:https://www.jb51.net/article/123579.htm jQuery处理键盘事件有三个函数,根据事件发生的顺序分别是: jquery 代码: 1.  keydown(); ...

  10. linux日常管理-vmstat命令

    系统负载用w查看.是什么原因造成了系统负载.查看系统负载状态 命令:vmstat vmstat就查看一次 vmstat 1 每秒钟更新一次.按ctrl+c取消. vmstat 1 5 每秒钟更新一次, ...