4

私はJavaでこのコードを持っています。

public class CloneTest implements Cloneable{
    String name;
    int marks;
    public CloneTest(String s, int i) {
        name = s;
        marks = i;
    }

    public void setName(String s) {
        name = s;
    }

    public void setMarks(int i) {
        marks = i;
    }

    @Override
    public Object clone() {
        return new CloneTest(this.name, this.marks);
    }
}

このクラスのオブジェクトを 1 つ作成し、それを複製しました。これで、name1 つのオブジェクトで の値を変更しても、もう一方のオブジェクトでは name の値は変更されません。ここで奇妙なのはコンストラクターにあります。name新しいStringforを作成するのではなく、単純な参照を使用しているだけですname。s は参照型であるため、クローンの も変更されるStringと予想していました。String誰が何が起こっているのか教えてもらえますか? 前もって感謝します!

編集

コードのテスト

CloneTest real = new CloneTest("Molly", 22);
CloneTest clone = real.clone();
real.setName("Dolly");

BlueJ の「Inspect Variables」機能を使用して値を確認しました。

4

5 に答える 5

4

が元のCloneTestoriginalオブジェクトの名前であり、メソッドを使用してcloned作成したクローン オブジェクトであるとします。originalclone()


1.cloned.nameとが同じオブジェクト (このoriginal.name場合は文字列) を指しています。
2. 次にoriginal.name、別の String オブジェクト ("Dolly") を指すように要求しました。これは、新しい String オブジェクト ("Dolly") を参照に割り当てると発生しますoriginal.name
3. しかし、cloned.nameまだ最初の String オブジェクト ("Dolly") を指しています。

したがって、cloned.nameまだ 1 番目の String オブジェクトを出力します。

ここで、参照を再割り当てせずに String オブジェクトの内容を変更できる場合、 の変更はclone.nameに反映されoriginal.nameます。ただし、String オブジェクトの場合、String の不変性のため、これは不可能です。ただし、いわば変更可能な文字列であるStringBuffersを使用して、cloneからへの変更を反映できます。同じコードの例を見てみましょう: https://gist.github.com/VijayKrishna/5967668original

于 2013-07-10T15:01:36.603 に答える
2

クラスの各インスタンスには、オブジェクトへの異なる参照があります。オブジェクトを変更するのではなく、参照を変更しているだけです。文字列をホルダーオブジェクトに配置し、それを複製してホルダー内に文字列を設定すると(ホルダー参照ではなく、ホルダー内の文字列参照)、両方のクローンに変更が加えられます

于 2013-07-10T15:05:06.730 に答える
0
package com.test;
class Manager implements Cloneable
{
String firstName;
String lastName;
int age;
public Manager(String fname,String lname,int a)
{
    this.firstName=fname;
    this.lastName=lname;
    this.age=a;
}
public String getFirstName() {
    return firstName;
}
public void setFirstName(String firstName) {
    this.firstName = firstName;
}
public String getLastName() {
    return lastName;
}
public void setLastName(String lastName) {
    this.lastName = lastName;
}
public int getAge() {
    return age;
}
public void setAge(int age) {
    this.age = age;
}
@Override
protected Object clone() throws CloneNotSupportedException {
    // TODO Auto-generated method stub
    return super.clone();
}

}

public class TestCloning {
public static void main(String[] args) throws CloneNotSupportedException {
    Manager m1=new Manager("Sadik","Tahir",26);
    Manager m_clone=(Manager)m1.clone();
    Manager m2=m1;
    System.out.println("M1 Details:::");
    System.out.println("Fisrt Name:"+m1.getFirstName()+",LastName:"+m1.getLastName()+",Age:"+m1.getAge());
    System.out.println("Hashcode:"+m1.hashCode());
    System.out.println("M_Clone Details:::");
    System.out.println("Fisrt Name:"+m_clone.getFirstName()+",LastName:"+m_clone.getLastName()+",Age:"+m_clone.getAge());
    System.out.println("Hashcode:"+m_clone.hashCode());
    System.out.println("M2 Details:::");
    System.out.println("Fisrt Name:"+m2.getFirstName()+",LastName:"+m2.getLastName()+",Age:"+m2.getAge());
    System.out.println("Hashcode:"+m2.hashCode());
    m1.setFirstName("Afreen");
    m1.setLastName("Khan");
    m1.setAge(25);
    System.out.println("M1 Details:::");
    System.out.println("Fisrt Name:"+m1.getFirstName()+",LastName:"+m1.getLastName()+",Age:"+m1.getAge());
    System.out.println("Hashcode:"+m1.hashCode());
    System.out.println("M_Clone Details:::");
    System.out.println("Fisrt Name:"+m_clone.getFirstName()+",LastName:"+m_clone.getLastName()+",Age:"+m_clone.getAge());
    System.out.println("Hashcode:"+m_clone.hashCode());
    System.out.println("M2 Details:::");
    System.out.println("Fisrt Name:"+m2.getFirstName()+",LastName:"+m2.getLastName()+",Age:"+m2.getAge());
    System.out.println("Hashcode:"+m2.hashCode());
}

}

于 2015-03-24T13:31:35.203 に答える
0

ハッシュコードを見て、@vijayの回答とともに明確に理解してください。

    CloneTest real = new CloneTest("Molly", 22);
    CloneTest clone = (CloneTest) real.clone();
    int h1=real.name.hashCode();
    int h2=clone.name.hashCode();
    System.out.println("h1 "  + h1  + " h2 " + h2); // same
    real.setName("sak");
    h1=real.name.hashCode();
    h2=clone.name.hashCode();
    System.out.println("h1 "  + h1  + " h2 " + h2); //different

出力:

 h1 74525175 h2 74525175
 h1 113629 h2 74525175
于 2013-07-10T15:31:09.753 に答える