Java深拷贝 内部类
在Java中,对象的拷贝是一个常见的操作。拷贝对象可以有两种方式,即浅拷贝和深拷贝。浅拷贝会创建一个新的对象,但是该对象的成员变量是原始对象中引用的副本。而深拷贝则是创建一个全新的对象,其中不仅仅包含原始对象的成员变量的副本,还包括成员变量引用的对象的副本。
Java中的内部类是一个嵌套在另一个类中的类。它有时被称为嵌套类。内部类可以直接访问其外部类的成员,包括私有成员。因此,内部类的拷贝相对于普通类的拷贝更加复杂。
浅拷贝和深拷贝
在深入讨论内部类的深拷贝之前,我们先了解一下浅拷贝和深拷贝的概念。
浅拷贝是指只复制对象的引用,而不复制引用指向的对象本身。这意味着,如果原始对象中的某个引用指向的对象发生了改变,那么拷贝对象中相应的引用也会发生改变。例如:
class Person {
String name;
public Person(String name) {
this.name = name;
}
}
Person p1 = new Person("Alice");
Person p2 = p1; // 浅拷贝
p1.name = "Bob";
System.out.println(p2.name); // 输出 "Bob"
深拷贝是指创建一个全新的对象,该对象的成员变量是原始对象成员变量的副本。这意味着,如果原始对象中的某个引用指向的对象发生了改变,拷贝对象中相应的引用不会发生改变。例如:
class Person {
String name;
public Person(String name) {
this.name = name;
}
}
Person p1 = new Person("Alice");
Person p2 = new Person(p1.name); // 深拷贝
p1.name = "Bob";
System.out.println(p2.name); // 输出 "Alice"
内部类的深拷贝
在Java中,内部类的深拷贝需要考虑两种情况:静态内部类和非静态内部类。
静态内部类的深拷贝
静态内部类是定义在另一个类中,并且使用static
关键字修饰的内部类。它可以被看作是独立于外部类的普通类。因此,静态内部类的深拷贝与普通类的深拷贝相同,可以使用构造函数或者拷贝函数来实现。
class OuterClass {
static class InnerClass {
String name;
public InnerClass(String name) {
this.name = name;
}
public InnerClass(InnerClass inner) {
this.name = inner.name;
}
}
}
OuterClass.InnerClass inner1 = new OuterClass.InnerClass("Alice");
OuterClass.InnerClass inner2 = new OuterClass.InnerClass(inner1); // 深拷贝
inner1.name = "Bob";
System.out.println(inner2.name); // 输出 "Alice"
非静态内部类的深拷贝
非静态内部类是定义在另一个类中的非静态成员类。它与外部类之间存在着一个隐式的引用关系。因此,非静态内部类的深拷贝需要在拷贝对象中包含对外部类的引用,并使用外部类的拷贝对象来创建内部类的拷贝对象。
class OuterClass {
class InnerClass {
String name;
public InnerClass(String name) {
this.name = name;
}
public InnerClass(OuterClass outer, InnerClass inner) {
outer.new InnerClass(inner.name);
}
}
}
OuterClass outer1 = new OuterClass();
OuterClass.InnerClass inner1 = outer1.new InnerClass("Alice");
OuterClass