Java基础--常用API--java.lang.Object
一、简述
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的更多相关文章
- Java 基础 常用API (Object类,String类,StringBuffer类)
Java API Java 的API(API: Application(应用) Programming(程序) Interface(接口)) Java API就是JDK中提供给我们使用的类,这些类将底 ...
- Java 基础 常用API (System类,Math类,Arrays, BigInteger,)
基本类型包装类 基本类型包装类概述 在实际程序使用中,程序界面上用户输入的数据都是以字符串类型进行存储的.而程序开发中,我们需要把字符串数据,根据需求转换成指定的基本数据类型,如年龄需要转换成int类 ...
- Java 基础 常用API ( 正则表达式,Date类,DateFormat类,Calendar类 )
正则表达式 正则表达式的概念 正则表达式(英语:Regular Expression,在代码中常简写为regex). 正则表达式是一个字符串,使用单个字符串来描述.用来定义匹配规则,匹配一系列符合某个 ...
- JAVA基础语法:java编程规范和常用数据类型(转载)
JAVA基础语法:java编程规范和常用数据类型 摘要 本文主要介绍了最基本的java程序规则,和常用数据类型,其中侧重说了数组的一些操作. 面向java编程 java是纯面向对象语言,所有的程序都要 ...
- java基础--常用函数总结
java基础--常用函数总结 2019-3-16-23:28:01-----云林原创 1.split()字符串分割函数 将一个字符串分割为子字符串,然后将结果作为字符串数组返回. 2.Math.flo ...
- Java基础16:Java多线程基础最全总结
Java基础16:Java多线程基础最全总结 Java中的线程 Java之父对线程的定义是: 线程是一个独立执行的调用序列,同一个进程的线程在同一时刻共享一些系统资源(比如文件句柄等)也能访问同一个进 ...
- 055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念
055 01 Android 零基础入门 01 Java基础语法 06 Java一维数组 02 数组的概念 本文知识点:数组的概念 数组的声明创建.初始化 在学习数组的声明创建.初始化前,我们可以和之 ...
- 039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述
039 01 Android 零基础入门 01 Java基础语法 05 Java流程控制之循环结构 01 循环结构概述 本文知识点:循环结构概述 循环结构主要内容 while 循环 do-whiile ...
- 020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结
020 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 14 变量与常量 知识总结 本文知识点:变量与常量 知识总结 Java中的标识符 Java中的关键字 目前常 ...
- 001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学
001 01 Android 零基础入门 01 Java基础语法 01 Java初识 01 导学 welcome to Java World 欢迎来到Java世界 一起领略Java编程世界的奥秘与奥妙 ...
随机推荐
- IO流 相关基础积累
一个整型32位字节. 写入到流.? 为什么要按十六进制输出到控制台?
- ffmpeg 纯静态编译,以及添加自定义库流程摘要
需求: 1. 纯静态编译ffmpeg ,即ldd ./ffmpeg 的结果是:not a dynamic executable 2. 修改ffmpeg 项目,添加自定义功能库 3. ...
- 本机不装Oracle,使用plsql连接远程Oracle的方法
由于Oracle的庞大,有时候我们需要在只安装Oracle客户端如plsql.toad等的情况下去连接远程数据库,可是没有安装Oracle就没有一切的配置文件去支持.最后终于发现一个很有效的方法,Or ...
- 分立元件封装尺寸及PCB板材工艺与设计实例
分立元件封装尺寸 inch mm (L)mm (w)mm (t)mm (a)mm (b)mm 0201 0603 0.6±0.05 0.30±0.05 0.23±0.05 0.10±0.05 0.60 ...
- INT 21H 指令说明及使用方法
很多初学汇编语言的同学可能会对INT 21H这条指令感到困惑,不知道是什么意思,下面就以一段简单的程序为大家讲解: 例如:需要键盘输入,并且回显. AH的值需要查表取得,表在下面 指令: M ...
- gradle项目搭建
一.gradle安装 1.安装JDK,这个就不用说了 2.下载gradle发布文件,下载地址:http://gradle.org/gradle-download/可以下载完整版或者简洁版都可以 3.解 ...
- C#中如何获取汉字的笔画数和汉字的拼音
以前玩过一个游戏,输入两个人的名字然后点击缘分就能产生一段缘分测试的结果,后来经过分析知道是根据名字笔画数之差来弄的小游戏,于是就在百度上找怎么得到汉字的笔画数,也没找到自己想要的答案,问遍了所有的人 ...
- Azure自动化部署服务 (1)
Azure中已经发布了自动化部署服务的PaaS功能. 本文将介绍自动化服务Automation初始化过程. 在Azure Management Portal上左边可以看到Azure的各种服务,其中一项 ...
- 【转】深刻理解render 和 redirect_to
由于最近老是在表单提交后出现没有反应的现象,发现是在action中的使用render 和 redirect_to的原因,于是就想搞清楚他两真正的区别在哪里,上一遍的blog也谈到了这二者的区别,但是有 ...
- RAC环境下ORACLE序列缓存导致序列混乱
目前项目中发现了这样一个问题,在数据库部署了RAC环境之后,偶尔会出现从Oracle Sequence所取出来的数是混乱的,比如第二次比第一次所取的数要小.这样当程序的逻辑依赖于ID的大小来排序时,就 ...