网站策划岗位要求,学校网站建设汇报,计算机培训机构一般多少钱,长春网站建设电话与 js的浅拷贝不同#xff1a;
在 JavaScript 中#xff0c; Object.assign() 或 spread 运算符等方法可以实现浅拷贝#xff0c;但只针对对象的第一层属性进行复制。如果一个对象只包含基本数据类型的属性#xff0c;那么对浅拷贝出来的对象进行修改不会影响原始对象
在 JavaScript 中 Object.assign() 或 spread 运算符等方法可以实现浅拷贝但只针对对象的第一层属性进行复制。如果一个对象只包含基本数据类型的属性那么对浅拷贝出来的对象进行修改不会影响原始对象因为它们拥有不同的内存地址。但是如果拷贝的对象包含引用类型的属性如数组、对象等那么拷贝出来的对象和原始对象会引用同一个内存地址因此如果在拷贝出来的对象上修改引用类型属性原始对象也会受到影响。
而在 Java 中浅拷贝通常无论对象是否只有一层都只是复制了对象的引用因此当对象包含引用类型的属性时浅拷贝出来的对象和原始对象也会引用同一个内存地址原始对象的修改会影响浅拷贝出来的对象。由于 Java 中基本类型和引用类型都需要使用 new 进行初始化所以浅拷贝并不会将基本类型的数据复制到新的对象中。 Java 中基本类型和引用类型都需要使用 new 进行初始化所以浅拷贝并不会将基本类型的数据复制到新的对象中。
class Person {String name;Person(String name) {this.name name;}
}public class Main {public static void main(String[] args) {String originalName John;String clonedName originalName;System.out.println(Original Name: originalName);System.out.println(Cloned Name: clonedName);clonedName Mike;System.out.println(Original Name: originalName);System.out.println(Cloned Name: clonedName);Person originalPerson new Person(John);Person clonedPerson originalPerson;System.out.println(Original Person Name: originalPerson.name);System.out.println(Cloned Person Name: clonedPerson.name);clonedPerson.name Mike;System.out.println(Original Person Name: originalPerson.name);System.out.println(Cloned Person Name: clonedPerson.name);}
}
在上述代码中我们首先定义了一个名为 originalName 的字符串变量并将其赋值为 John。然后我们将 originalName 的值赋给 clonedName 变量。输出结果显示 originalName 和 clonedName 的值都是 John。
接着我们将 clonedName 的值修改为 Mike。输出结果显示 originalName 的值仍然是 John而 clonedName 的值变成了 Mike。这是因为字符串是不可变类型所以在将 originalName 的值赋给 clonedName 时实际上是创建了一个新的字符串对象。
然后我们定义了一个名为 Person 的类其中包含一个 name 字符串属性。在 main 函数中我们实例化了一个 originalPerson 对象并将其赋给 clonedPerson 变量。输出结果显示 originalPerson 和 clonedPerson 的 name 属性值都是 John。
然后我们将 clonedPerson 的 name 属性值修改为 Mike。输出结果显示 originalPerson 和 clonedPerson 的 name 属性值都变成了 Mike。这是因为对象是引用类型originalPerson 和 clonedPerson 实际上指向了同一个对象修改其中一个对象的属性会影响到另一个对象。
因此上述代码示例说明了基本类型和引用类型在赋值时的区别。在浅拷贝中基本类型的数据并不会被复制到新的对象中而是共享同一份数据而引用类型的数据则会被共享。 【这是因为字符串是不可变类型所以在将 originalName 的值赋给 clonedName 时实际上是创建了一个新的字符串对象。】 这句话解释了为什么 【25行代码修改了Apple为Orange】但是arrarList却米有受到影响。【由于String 对象是一旦声明不可变的所以当arrarList1修改的时候arrayList1.get(0)的对象引用已经指向了一个新的对象】。所以 arrayList.get(0) 还是原来的值。 myClass m new myClass(王明);ArrayListmyClass list new ArrayList();list.add(m);ArrayListmyClass list2 (ArrayList) list.clone();list2.get(0).a 李明;System.out.println(list.get(0).a);System.out.println(list2.get(0).a); 为什么 需要 (ArrayList) 强制转型在对 list.clone() 进行调用时返回的是一个 Object 类型的对象而不是 ArrayListmyClass 类型的对象。这是因为 clone() 方法返回的是一个浅拷贝的对象其继承自 Object 类。因此为了将其转换为 ArrayListmyClass 类型需要进行强制类型转换。在上述代码中我们创建了一个名为 myClass 的类其中包含一个名为 a 的字符串属性。首先我们创建了一个 myClass 对象 m并将其添加到 ArrayListmyClass 类型的列表 list 中。然后我们使用 clone() 方法创建了一个 list2 的副本对象。注意clone() 方法返回的是一个浅拷贝的对象即 list2 和 list 引用的是同一个内存地址其中的元素也是共享的。因此当我们在 list2 中修改元素的属性值时list 中对应的元素也会受到影响。为了避免编译器产生警告我们使用了 (ArrayList) 进行强制类型转换将返回的 Object 类型对象转换为 ArrayListmyClass 类型。