先用一个例子来说明假克隆吧,也就是用“=”之后的效果、。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
public class Employee{
public Employee(){
}
public Employee(String name, int age){
this .age = age;
this .name = name;
}
@Override
public String toString(){
return "姓名: " + name + "年龄: " + 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;
}
public static void main(String[] args){
Employee demo1 = new Employee( "rollen" , 20 );
System.out.println(demo1);
Employee demo2 = demo1;
demo2.setAge( 100 );
demo2.setName( "hello world" );
System.out.println(demo1);
System.out.println(demo2);
}
private String name;
private int age;
} |
【运行结果】:
【运行结果】
姓名: rollen年龄: 20
姓名: hello world年龄: 100
姓名: hello world年龄: 100
下面看看java中的浅拷贝
对于类中的每个域,如果只包含基本类型或者不可变的引用类型,如String,或者对象在其生命周期内不会发生变化,则可以使用浅拷贝来复制对象,但是一般使用深拷贝。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
class Address{
public Address(){
}
public Address(String state, int number){
this .number = number;
this .state = state;
}
@Override
public String toString(){
return "state: " + state + " munber: " + number;
}
public String getState(){
return state;
}
public void setState(String state){
this .state = state;
}
public int getNumber(){
return number;
}
public void setNumber( int number){
this .number = number;
}
private String state;
private int number;
} public class Employee implements Cloneable{
public Employee(){
}
public Employee(String name, int age, Address address){
this .address = address;
this .age = age;
this .name = name;
}
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;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this .address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append( "name:" + name + ", " );
sb.append( "age:" + age + " \n" );
sb.append( "Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null ;
try {
employee = (Employee) super .clone();
} catch (CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println( "克隆之前:" );
Address add1 = new Address( "中国" , 1 );
Employee emp1 = new Employee( "rollen" , 20 , add1);
System.out.println(emp1);
System.out.println( "克隆之后" );
Employee emp2 = emp1.clone();
emp2.setName( "hello world" );
emp2.setAge( 100 );
emp2.address.setNumber( 2 );
emp2.address.setState( "美国" );
System.out.println(emp1);
System.out.println( "-----" );
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
} |
【运行结果】:
克隆之前:
name:rollen, age:20
Address: state: 中国 munber: 1
克隆之后
name:rollen, age:20
Address: state: 美国 munber: 2
-----
name:hello world, age:100
Address: state: 美国 munber: 2
但是上面的主函数中的:
1
2
|
// emp2.address.setNumber(2); // emp2.address.setState("美国"); |
替换为:
1
|
emp2.setAddress( new Address( "美国" , 2 ));
|
运行结果为:
克隆之前:
name:rollen, age:20
Address: number: 1state中国
克隆之后
name:rollen, age:20
Address: number: 1state中国
-----
name:hello world, age:100
Address: number: 2state美国
这里我有点不明白了,为什么这种情况下克隆之后两个address会不一样呢?
谁帮忙指点一下,谢谢了、
现在看看java对象的深克隆
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
|
class Address implements Cloneable{
public Address(){
}
public Address(String state, int number){
this .number = number;
this .state = state;
}
@Override
public String toString(){
return "state: " + state + " munber: " + number;
}
@Override
protected Address clone() throws CloneNotSupportedException{
Address address = null ;
address = (Address) super .clone();
return address;
}
public String getState(){
return state;
}
public void setState(String state){
this .state = state;
}
public int getNumber(){
return number;
}
public void setNumber( int number){
this .number = number;
}
private String state;
private int number;
} public class Employee implements Cloneable{
public Employee(){
}
public Employee(String name, int age, Address address){
this .address = address;
this .age = age;
this .name = name;
}
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;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this .address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append( "name:" + name + ", " );
sb.append( "age:" + age + " \n" );
sb.append( "Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null ;
try {
employee = (Employee) super .clone();
employee.address = address.clone(); } catch (CloneNotSupportedException e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println( "克隆之前:" );
Address add1 = new Address( "中国" , 1 );
Employee emp1 = new Employee( "rollen" , 20 , add1);
System.out.println(emp1);
System.out.println( "克隆之后" );
Employee emp2 = emp1.clone();
emp2.setName( "hello world" );
emp2.setAge( 100 );
emp2.setAddress( new Address( "美国" , 2 ));
System.out.println(emp1);
System.out.println( "-----" );
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
} |
【运行结果】:
【运行结果】:
克隆之前:
name:rollen, age:20
Address: state: 中国 munber: 1
克隆之后
name:rollen, age:20
Address: state: 中国 munber: 1
-----
name:hello world, age:100
Address: state: 美国 munber: 2
序列化接口和对象克隆
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
|
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
class Address implements Serializable{
public Address(){
}
public Address(String state, int number){
this .number = number;
this .state = state;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append( "number: " + number);
sb.append( "state" + state + "\n" );
return sb.toString();
}
public String getState(){
return state;
}
public void setState(String state){
this .state = state;
}
public int getNumber(){
return number;
}
public void setNumber( int number){
this .number = number;
}
private String state;
private int number;
} public class Employee implements Cloneable, Serializable{
public Employee(){
}
public Employee(String name, int age, Address address){
this .address = address;
this .age = age;
this .name = name;
}
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;
}
public Address getAddress(){
return address;
}
public void setAddress(Address address){
this .address = address;
}
@Override
public String toString(){
StringBuilder sb = new StringBuilder();
sb.append( "name:" + name + ", " );
sb.append( "age:" + age + " \n" );
sb.append( "Address: " + address);
return sb.toString();
}
@Override
protected Employee clone(){
Employee employee = null ;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject( this );
oos.close();
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
employee = (Employee) ois.readObject();
ois.close();
} catch (Exception e){
e.printStackTrace();
}
return employee;
}
public static void main(String[] args){
System.out.println( "克隆之前:" );
Address add1 = new Address( "中国" , 1 );
Employee emp1 = new Employee( "rollen" , 20 , add1);
System.out.println(emp1);
System.out.println( "克隆之后" );
Employee emp2 = emp1.clone();
emp2.setName( "hello world" );
emp2.setAge( 100 );
emp2.address.setNumber( 2 );
emp2.address.setState( "美国" );
System.out.println(emp1);
System.out.println( "-----" );
System.out.println(emp2);
}
private String name;
private int age;
private Address address;
} |
【运行结果】:
克隆之前:
name:rollen, age:20
Address: number: 1state中国
克隆之后
name:rollen, age:20
Address: number: 1state中国
-----
name:hello world, age:100
Address: number: 2state美国
对于任何一个序列化的对象,都必须要求实现Serializable接口。其次,如果这个类的域中也有引用对象,则也有要求这个引用类型也实现这个接口,。最后,序列化方式实现克隆效率不高,没有直接深度克隆的效率高。有兴趣的朋友 可以测试一下。
相关推荐
实现深克隆可能需要自定义的克隆方法,或者使用序列化和反序列化技术。 4. **示例**:`克隆.txt`可能包含以下示例代码: ```java class MyClass implements Cloneable { private Object nestedObj; public ...
Java 序列化和反序列化是 Java 语言中的一种机制,用于将对象转换为字节流,以便在网络上传输或存储。序列化是将对象转换为字节流的过程,而反序列化是将字节流转换回对象的过程。 在 Java 中,序列化和反序列化是...
虽然序列化和克隆都能创建对象的副本,但二者有本质区别。序列化涉及将对象转换为字节流,而克隆是直接创建一个与原对象具有相同属性的新对象,通常通过实现`Cloneable`接口并覆盖`clone()`方法来实现。 9. **序列...
Java中的对象序列化是一种将Java对象转换为字节流的过程,以便可以持久存储或在网络上传输...虽然大部分时候无需编写自定义代码,但在某些复杂情况,可能需要定制序列化和反序列化逻辑以确保正确处理特定对象的序列化。
1. **对象序列化的基本用法**:如何在类中声明`Serializable`接口,以及如何使用`ObjectOutputStream`和`ObjectInputStream`进行序列化和反序列化操作。 2. **序列化与持久化**:讨论了如何通过序列化将对象的状态...
首先,要使一个Java对象能够被序列化,该类必须实现`Serializable`接口。这个接口没有任何方法,仅仅是一个标记接口,表明该类的对象可以被序列化。当一个类实现了这个接口,Java运行时系统就能够将其实例转换为字节...
序列化和对象的浅复制(克隆)都是保存对象状态的方式,但两者有本质区别。序列化是将整个对象转换为字节流,而克隆是创建对象的一个副本,通常只复制对象的直接属性,不涉及深层引用。 了解以上知识点后,Java...
3. **对象克隆**:通过序列化和反序列化实现对象的深度克隆。 4. **缓存机制**:将对象状态存储到磁盘或内存中,以提高性能。 #### 三、序列化实现机制 Java提供了两种主要的序列化方式: 1. **标准序列化**(`...
- 对于实现`Serializable`接口的类,应考虑实现`writeObject()`和`readObject()`方法来自定义序列化和反序列化行为,以处理特定的逻辑或敏感数据。 **使用示例**: ```java public class PersonalData implements ...
Java的序列化机制允许开发者在类中定义`readObject()`和`writeObject()`方法来自定义序列化和反序列化的行为,或者使用`transient`关键字来排除某些字段不参与序列化。 总之,Java序列化是一个强大的工具,它使得...
1. **实现Serializable接口**:这是通过序列化和反序列化实现深拷贝的方法。首先将对象转换为字节数组,然后从这个字节数组中反序列化出一个新的对象。这种方法简单,但不适用于所有对象,因为有些对象可能不适合...
Java序列化机制是Java语言中一项非常实用的功能,它极大地简化了对象在网络传输和持久化过程中的处理。通过深入了解序列化的原理和算法流程,开发者可以更好地利用这项技术解决实际问题。在未来的学习和工作中,掌握...
在 Java 中,序列化是一种用于处理对象流的机制,它可以将对象的内容进行流化,使其可以被读写和传输。下面是 10 个与 Java 序列化相关的面试题目: 1. 什么是 Java 序列化,如何实现 Java 序列化? Java 序列化是...
总的来说,Java对象序列化提供了一种强大的工具,让我们能够在各种场景下保存和恢复对象的状态。无论是为了持久化数据、跨网络传输对象还是在分布式环境中复制状态,了解和熟练使用序列化都是Java开发者的必备技能。
总结,Java中的对象克隆是一项重要的功能,用于复制和独立化对象。通过实现`Cloneable`接口和覆盖`clone()`方法,我们可以创建浅克隆对象。对于更复杂的场景,可以自定义克隆逻辑或利用序列化来实现深克隆。理解并...
总之,Java对象的序列化可以通过`transient`关键字来排除某些字段,同时可以利用`writeObject()`和`readObject()`方法自定义序列化和反序列化的行为,以满足特定需求,例如处理`transient`字段的序列化,以及在网络...
总的来说,Java对象的序列化和反序列化是一种强大的工具,能够帮助开发者在多种场景下管理对象的状态,提高程序的灵活性和可维护性。然而,使用时也需谨慎,尤其是在涉及敏感数据和跨版本兼容性问题时。
Jackson是Java领域中广泛使用的JSON处理库,它提供了高效的JSON序列化和反序列化功能。在Java应用程序中,我们经常需要将Java对象转换为JSON字符串(序列化)或从JSON字符串恢复Java对象(反序列化),Jackson库就是...
在Java编程中,序列化和反序列化是两个重要的概念。序列化(Serialization)是指把一个Java对象变成字节流的过程,而反序列化(Deserialization)则是将这个字节流恢复为Java对象的过程。序列化主要的目的是为了保存...
总的来说,Java的对象序列化和克隆是两个重要的概念,它们在数据持久化、网络通信等方面有着广泛的应用。通过理解这些技术,开发者可以更好地设计和实现复杂的系统,提高代码的可维护性和复用性。