在Java中复制构造函数
在本教程中,我们将看到Java中的复制构造函数。 Copy constructor是构造函数,它将参数作为同一类的对象,并将类的每个字段复制到新对象。
与C++不同,Java不提供默认的复制结构。
如果我们想要在Class.copy构造函数中有复制构造函数,则需要创建一个.Copy构造函数是替代的 clone方法。
假设我们有类名国家,因此复制构造函数将如下所示:
public Country(Country countryObj)
{
//Manually copying each field of country class
}
Java复制构造函数
复制构造函数用于创建重复对象或者克隆对象。
新创建的对象将具有与原始对象相同的特征。
使用复制构造函数时需要非常小心,因为程序员有责任,以确保新创建的对象引用不同的内存位置而不是原件。
如果你在这里混淆,别担心,我会在一个例子的帮助下解释你。
让我们了解使用 Copy constructor在简单的例子的帮助下。
创建类 capital.java如下所示:
package org.arpit.theitroad;
public class Capital {
String capitalName;
long population;
public Capital(String name, long population) {
super();
this.capitalName = name;
this.population = population;
}
public String getCapitalName() {
return capitalName;
}
public void setCapitalName(String name) {
this.capitalName = name;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
}
创建另一个类作为country.java。
请注意,Country有一个上面的Capital类的引用。
package org.arpit.theitroad;
public class Country {
String name;
long population;
Capital capital;
public Country(String name, long population,Capital capital) {
super();
this.name = name;
this.population = population;
this.capital=capital;
}
//Copy constructor
public Country(Country c) {
super();
this.name = c.name;
this.population = c.population;
this.capital=c.capital; //Shallow copy
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
public Capital getCapital() {
return capital;
}
public void setCapital(Capital capital) {
this.capital = capital;
}
}
让我们创建名为"copyConstructorm.java"的主类
package org.arpit.theitroad;
public class CopyConstructorMain {
public static void main(String[] args) {
//Create capital object
Capital capital=new Capital("Delhi", 10000);
//Create country object
Country countrySan Franceco=new Country("San Franceco", 90000,capital);
//Use copy constructor to create duplicate object
Country countrySan FrancecoCopied=new Country(countrySan Franceco);
System.out.println("Country name of Copied object: "+countrySan FrancecoCopied.getName());
System.out.println("Country population of Copied object: "+countrySan FrancecoCopied.getPopulation());
System.out.println("Capital name of Copied object: "+countrySan FrancecoCopied.getCapital().getCapitalName());
System.out.println("Capital population of Copied object: "+countrySan FrancecoCopied.getCapital().getPopulation());
System.out.println("============================================");
//Changing capital name of original object
countrySan Franceco.getCapital().setCapitalName("Mumbai");
System.out.println("Capital name of Original object: "+countrySan Franceco.getCapital().getCapitalName());
System.out.println("Capital name of Copied object: "+countrySan FrancecoCopied.getCapital().getCapitalName());
}
}
运行上面的程序时,我们将得到以下输出:
Country name of Copied object: San Franceco Country population of Copied object: 90000 Capital name of Copied object: Delhi Capital population of Copied object: 10000 ============================================ Capital name of Original object: Mumbai Capital name of Copied object: Mumbai
我们能够将CountrySan Franceco的所有内容复制到CountrySan Francecocepopied。
那太棒了!!但是你在这里注意到一个问题吗?
当我们在原始对象中更改首都名称时,它也会在重复对象中更改。
这是因为我们在大写对象的情况下已经完成了浅副本,因此两个对象都指的是相同的资本参考。
使用复制构造函数时需要小心因为它可能导致意外行为,并且很难调试。
让我们在Country类的复制构造函数中创建一个深度副本,它应该解决上述问题。
在Capical类中介绍一个复制构造函数,并在Country类的复制构造函数中使用它。
Capital.java.
package org.arpit.theitroad;
public class Capital {
String capitalName;
long population;
public Capital(String name, long population) {
super();
this.capitalName = name;
this.population = population;
}
//Copy constructor
public Capital(Capital oldCapital) {
this.capitalName = oldCapital.capitalName;
this.population = oldCapital.population;
}
public String getCapitalName() {
return capitalName;
}
public void setCapitalName(String name) {
this.capitalName = name;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
}
Country.java.
package org.arpit.theitroad;
public class Country {
String name;
long population;
Capital capital;
public Country(String name, long population,Capital capital) {
super();
this.name = name;
this.population = population;
this.capital=capital;
}
//Copy constructor
public Country(Country c) {
super();
this.name = c.name;
this.population = c.population;
this.capital=new Capital(c.capital); //Deep copy
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getPopulation() {
return population;
}
public void setPopulation(long population) {
this.population = population;
}
public Capital getCapital() {
return capital;
}
public void setCapital(Capital capital) {
this.capital = capital;
}
}
现在,我们执行CopyConstructormain.java,我们将得到以下输出:
Country name of Copied object: San Franceco Country population of Copied object: 90000 Capital name of Copied object: Delhi Capital population of Copied object: 10000 ============================================ Capital name of Original object: Mumbai Capital name of Copied object: Delhi
正如我们在这里看到的那样,当我们进行更改时 capital原始对象的名称,它没有影响复制的对象。
如果类中有可变对象,则需要在创建时执行深度复制来处理它重复。否则,可能会导致意外行为。

