Object类的典型应用

Java克隆机制详解

1.Object类关于自定义实现“克隆”的步骤

  1. 自定义类实现Cloneable接口,实现该接口的对象可以实现“自我克隆”。
  2. 自定义类实现自己的clone()方法。
  3. 实现clone()方法时通过super.clone():调用Object实现的clone()方法来得到对象的副本,并返回该副本。

2.代码示例

class Address
{
	String detail;
	public Address(String detail)
	{
		this.detail = detail;
	}
}

//实现Cloneable接口
class User implements Cloneable
{
	int age;
	Address address;
	public User(int age)
	{
		this.age = age;
		address = new Address("西安");
	}
	// 通过调用super.clone()来实现clone()方法
	public User clone()
		throws CloneNotSupportedException
	{
		return (User)super.clone();
	}
}

public class CloneTest {
	public static void main(String[] args)
	throws CloneNotSupportedException
	{
		User u1 = new User(29);
		// clone得到u1对象的副本。
		User u2 = u1.clone();
		// 判断u1、u2是否相同
		System.out.println(u1 == u2);      //①
		// 判断u1、u2的address是否相同
		System.out.println(u1.address == u2.address);     //②
	}

}

 

3.运行结果

false
true

 

4.Object类提供的克隆机制图

 Object类的clone()方法虽然简单易用,但它只是一种“浅克隆”,它只克隆该对象的所有成员变量值,不对引用类型的成员值所引用的对象进行克隆,该类提供的克隆机制如下图。



 

 

解压后,150M随书源代码 第1章 利用单片机开发板实现自动化控制  第1节 设计说明  第2节 模拟量输入程序设计   例1 利用keil c5l实现单片机模拟电压输入   例2 利用汇编语言实现单片机模拟电压输入   例3 利用c++builder实现pc与单片机模拟电压输入   例4 利用visual c++实现pc与单片机模拟电压输入   例5 利用labwindows/cvi实现pc与单片机模拟电压输入  第3节 模拟量输出程序设计   例6 利用keil c51实现单片机模拟电压输出   例7 利用汇编语言实现单片机模拟电压输出   例8 利用c++builder实现pc与单片机模拟电压输出   例9 利用visual c++实现pc与单片机模拟电压输出   例10 利用labwindows/cvi实现pc与单片机模拟电压输出  第4节 数字量输入程序设计   例11 利用keil c51实现单片机数字量输入   例12 利用汇编语言实现单片机数字量输入   例13 利用c++builder实现pc与单片机数字量输入   例14 利用visual c++实现pc与单片机数字量输入 .  例15 利用labwindows/cvi实现pc与单片机数字量输入  第5节 数字量输出程序设计   例16 利用keil c51实现单片机数字量输出   例17 利用汇编语言实现单片机数字量输出   例18 利用c++builder实现pc与单片机数字量输出   例19 利用visual c++实现pc与单片机数字量输出   例20 利用labwindows/cvi实现pc与单片机数字量输出 第2章 利用plc实现自动化控制  第1节 设计说明  第2节 模拟量输入程序设计   例21 三菱fx2n plc模拟电压输入程序   例22 利用c++builder实现pc与fx2n plc模拟电压输入   例23 利用visual c++实现pc与fx2n plc模拟电压输入   例24 利用labwindows/cvi实现pc与fx2n plc模拟电压输入  第3节 模拟量输出程序设计   例25 三菱fx2n plc模拟电压输出程序   例26 利用c++builder实现pc与fx2n plc模拟电压输出   例27 利用visual c++实现pc与fx2n plc模拟电压输出   例28 利用labwindows/cvi实现pc与fx2n plc模拟电压输出  第4节 数字量输入程序设计   例29 利用c++builder实现pc与fx2n plc数字量输入   例30 利用visual c++实现pc与fx2n plc数字量输入   例31 利用labwindows/cvi实现pc与fx2n plc数字量输入  第5节 数字量输出程序设计   例32 利用c++builder实现pc与fx2n plc数字量输出   例33 利用visual c++实现pc与fx2n plc数字量输出   例34 利用labwindows/cvi实现pc与fx2n plc数字量输出  第6节 数字量输入与输出程序设计   例35 西门子s7-200 plc数字量输入与输出程序   例36 利用c++builder实现pc与s7-200 plc数字量输入与输出   例37 利用visual c++实现pc与s7-200 plc数字量输入与输出   例38 利用labwindows/cvi实现pc与s7-200 plc数字量输入与输出 第3章 利用数据采集卡实现自动化控制  第1节 设计说明  第2节 模拟量输入程序设计   例39 利用c++builder实现pc与pci数据采集卡模拟电压输入   例40 利用visual c++实现pc与pci数据采集卡模拟电压输入   例41 利用labwindows/cvi实现pc与pci数据采集卡模拟电压输入  第3节 模拟量输出程序设计   例42 利用c++builder实现pc与pci数据采集卡模拟电压输出   例43 利用visual c++实现pc与pci数据采集卡模拟电压输出   例44 利用labwindows/cvi实现pc与pci数据采集卡模拟电压输出  第4节 数字量输入程序设计   例45 利用c++builder实现pc与pci数据采集卡数字量输入   例46 利用visual c++实现pc与pci数据采集卡数字量输入   例47 利用labwindows/cvi实现pc与pci数据采集卡数字量输入  第5节 数字量输出程序设计   例48 利用c++builder实现pc与pci数据采集卡数字量输出   例49 利用visual c++实现pc与pci数据采集卡数字量输出   例50 利用labwindows/cvi实现pc与pci数据采集卡数字量输出 第4章 利用usb数据采集板实现自动化控制  第1节 设计说明  第2节 模拟量输入程序设计   例51 利用c++builder实现pc与usb数据采集板模拟电压输入   例52 利用visual c++实现pc与ljsb数据采集板模拟电压输入   例53 利用labwindows/cvi实现pc与usb数据采集板模拟电压输入  第3节 模拟量输出程序设计   例54 利用c++builder实现pc与usb数据采集板模拟电压输出   例55 利用visual c++实现pc与usb数据采集板模拟电压输出   例56 利用labwindows/cvi实现pc与usb数据采集板模拟电压输出  第4节 数字量输入程序设计   例57 利用c++builder实现pc与usb数据采集板数字量输入   例58 利用visual c++实现pc与usb数据采集板数字量输入   例59 利用labwindows/cvi实现pc与usb数据采集板数字量输入  第5节 数字量输出程序设计   例60 利用c++builder实现pc与usb数据采集板数字量输出   例61 利用visual c++实现pc与usb数据采集板数字量输出   例62 利用labwindows/cvi实现pc与usb数据采集板数字量输出 第5章 利用can数据采集模块实现数据采集与控制  第1节 设计说明  第2节 模拟量输入程序设计   例63 利用c++builder实现pc与can数据采集模块模拟电压输入   例64 利用visual c++实现pc与can数据采集模块模拟电压输入   例65 利用labwindows/cvi实现pc与can数据采集模块模拟电压输入  第3节 模拟量输出程序设计   例66 利用c++builder实现pc与can数据采集模块模拟电压输出   例67 利用visual c++实现pc与can数据采集模块模拟电压输出   例68 利用labwindows/cvi实现pc与can数据采集模块模拟电压输出  第4节 数字量输入程序设计   例69 利用c++builder实现pc与can数据采集模块数字量输入   例70 利用visual c++实现pc与can数据采集模块数字量输入   例71 利用labwindows/cvi实现pc与can数据采集模块数字量输入  第5节 数字量输出程序设计   例72 利用c++builder实现pc与can数据采集模块数字量输出   例73 利用visual c++实现pc与can数据采集模块数字量输出   例74 利用labwindows/cvi实现pc与can数据采集模块数字量输出 第6章 利用远程i/o模块实现自动化控制  第1节 设计说明  第2节 模拟电压输入程序设计   例75 利用c++builder实现pc与远程i/o模块模拟电压输入   例76 利用visual c++实现pc与远程i/o模块模拟电压输入   例77 利用labwindows/cvi实现pc与远程i/o模块模拟电压输入  第3节 模拟电压输出程序设计   例78 利用c++builder实现pc与远程i/o模块模拟电压输出   例79 利用visual c++实现pc与远程i/o模块模拟电压输出   例80 利用labwindows/cvi实现pc与远程i/o模块模拟电压输出  第4节 数字量输入程序设计   例81 利用c++builder实现pc与远程i/o模块数字量输入   例82 利用visual c++实现pc与远程i/o模块数字量输入   例83 利用labwindows/cvi实现pc与远程i/o模块数字量输入  第5节 数字量输出程序设计   例84 利用c++builder实现pc与远程i/o模块数字量输出   例85 利用visual c++实现pc与远程i/o模块数字量输出   例86 利用labwindows/cvi实现pc与远程i/o模块数字量输出
<think>我们正在讨论Java中的Object,它是所有Java的根。根据引用资料,我们可以总结以下关键点: 1. Object是所有的父(根)。如果一个没有显式继承其他,那么它隐式继承Object。 2. Object包含一些重要的方法,如equals(), hashCode(), toString(), getClass()等,这些方法可以被所有Java对象使用。 3. 由于多态性,Object的引用可以指向任何对象(引用型)。 4. 当创建任何的对象时,都会访问Object的无参构造方法(因为Object是顶级父)。 5. Object中的equals方法默认是比较两个对象的地址(即“==”操作符),如果要比较对象内容,需要重写equals方法(例如String就重写了equals)。 6. hashCode方法返回对象的哈希码(基于内存地址的整数表示),但需要注意的是,两个对象的哈希码相同并不意味着对象相同(可能发生哈希碰撞),只有相同的对象(地址相同)哈希码才一定相同。 7. getClass()方法返回对象的运行时的Class对象,通过Class对象可以获取的元数据(如名、方法、字段等)。 现在,我们将详细介绍Object的主要方法: ### 1. equals(Object obj) - **定义**:`public boolean equals(Object obj)` - **默认实现**:比较两个对象的地址是否相同(即`this == obj`)[^1][^3] - **重写规则**:为了比较对象的内容,子需要重写此方法(如String、Integer等包装) - **重写要求**: - 自反性:`x.equals(x)`为true - 对称性:如果`x.equals(y)`为true,则`y.equals(x)`也为true - 传递性:如果`x.equals(y)`为true且`y.equals(z)`为true,则`x.equals(z)`为true - 一致性:多次调用结果一致 - 非空性:`x.equals(null)`返回false ### 2. hashCode() - **定义**:`public native int hashCode()` - **作用**:返回对象的哈希码值(整数)[^2] - **规则**: - 同一对象多次调用返回相同整数 - 如果两个对象通过`equals`方法相等,则它们的哈希码必须相同 - 但两个对象哈希码相同,不一定`equals`(哈希碰撞) - **注意**:重写`equals`时必须同时重写`hashCode`,否则违反上述规则(如HashMap等集合依赖此规则) ### 3. toString() - **定义**:`public String toString()` - **默认实现**:返回名@哈希码的十六进制表示(如`java.lang.Object@1b6d3586`) - **重写意义**:提供对象的可读表示(如String重写后返回字符串本身) ### 4. getClass() - **定义**:`public final native Class<?> getClass()` - **作用**:返回对象的运行时(Class对象)[^2] - **应用**:反射机制的基础 ### 5. clone() - **定义**:`protected native Object clone() throws CloneNotSupportedException` - **作用**:创建并返回对象的副本(浅拷贝) - **要求**:必须实现`Cloneable`接口,否则抛出异常 ### 6. finalize() - **定义**:`protected void finalize() throws Throwable` - **作用**:垃圾回收器在回收对象前调用(已废弃,不推荐使用) ### 使用示例 ```java public class Person { private String name; private int age; // 构造方法省略... @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Person person = (Person) o; return age == person.age && Objects.equals(name, person.name); } @Override public int hashCode() { return Objects.hash(name, age); } @Override public String toString() { return "Person{name='" + name + "', age=" + age + "}"; } } ``` ### 多态应用 ```java public class Test { public static void main(String[] args) { Object obj = new Person("Alice", 30); // Object引用指向Person对象 System.out.println(obj.toString()); // 输出: Person{name='Alice', age=30} } } ``` ### 注意事项 - **比较对象内容**:必须重写`equals`和`hashCode`(如集合框架中的HashSet、HashMap依赖这两个方法) - **获取信息**:通过`getClass()`可以动态获取信息(反射) - **克隆对象**:优先使用拷贝构造器或`Cloneable`接口(注意深拷贝/浅拷贝问题) --- §§相关问题§§ 1. 为什么重写equals方法时必须同时重写hashCode方法? 2. Object的finalize方法为什么被废弃?替代方案是什么? 3. 如何正确实现对象的深拷贝? 4. 如何通过反射获取Object中定义的方法? [^1]: Object中的equals方法定义[^1] [^2]: Object的基本特性和getClass方法[^2] [^3]: equals方法的重写必要性[^3] [^4]: equals方法在字符串比较中的应用[^4] </think>### Java Object详解 #### 一、核心地位 1. **根特性** - 所有的隐式父(未显式继承时自动继承) $$ \text{class MyClass \{...\} } \implies \text{等价于 class MyClass extends Object \{...\}} $$ - Java单继承体系的顶点[^2] 2. **多态应用** ```java public void process(Object obj) { // 可接受任意对象 System.out.println(obj.getClass()); } ``` #### 二、关键方法解析 ##### 1. equals(Object obj) - **默认实现** ```java public boolean equals(Object obj) { return (this == obj); // 比较对象地址[^1][^3] } ``` - **重写规则** | 特性 | 要求 | |------------|-------------------------------| | 自反性 | `x.equals(x) == true` | | 对称性 | `x.equals(y) == y.equals(x)` | | 传递性 | `x.equals(y) && y.equals(z) => x.equals(z)` | | 一致性 | 多次调用结果相同 | | 非空性 | `x.equals(null) == false` | - **示例对比** ```java String s = "hello"; StringBuilder sb = new StringBuilder("hello"); // false: String.equals()会检查对象型[^4] System.out.println(s.equals(sb)); // false: StringBuilder未重写equals,使用Object默认实现[^4] System.out.println(sb.equals(s)); ``` ##### 2. hashCode() - **内存映射** ```mermaid graph LR A[对象内存地址] --> B[哈希函数] B --> C[整数哈希码] ``` - **契约要求** - 对象相等 $\implies$ 哈希码必须相等 - 哈希码相等 $\not\Rightarrow$ 对象相等(哈希碰撞) ##### 3. getClass() - **反射基础** ```java Student stu = new Student(); Class<?> clazz = stu.getClass(); System.out.println(clazz.getName()); // 输出完整名[^2] ``` ##### 4. toString() - **默认实现** ```java public String toString() { return getClass().getName() + "@" + Integer.toHexString(hashCode()); } // 输出示例: com.example.Student@1b6d3586 ``` #### 三、核心特性对比 | 方法 | 默认行为 | 重写必要性 | |--------------|--------------------------|------------------| | `equals()` | 地址比较 | 值对象必须重写 | | `hashCode()` | 内存地址派生整数 | 需与equals同步 | | `toString()` | 名@十六进制哈希值 | 建议重写增强可读 | | `getClass()` | 返回运行时对象 | 通常不需重写 | | `clone()` | 浅拷贝(需实现Cloneable)| 深拷贝需重写 | #### 四、设计原理 1. **模板方法模式** - 提供基础方法骨架(如`toString()`) - 允许子重写具体实现 2. **契约设计** - `equals()`与`hashCode()`的联动约束 ```java // 正确重写示例 @Override public int hashCode() { return Objects.hash(name, age); // 基于相同字段 } ``` #### 五、典型应用场景 1. **泛型容器** ```java List<Object> list = new ArrayList<>(); list.add("String"); list.add(123); // 自动装箱Integer ``` 2. **反射机制** ```java Method[] methods = obj.getClass().getDeclaredMethods(); ``` 3. **对象比较** ```java public boolean compare(User u1, User u2) { return u1.equals(u2); // 依赖重写的equals } ``` ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值