java/android:克隆/复制后编辑对象也会编辑原始对象

java/android:克隆/复制后编辑对象也会编辑原始对象,java,android,clone,Java,Android,Clone,我用两种不同的策略“克隆”了一个对象。克隆构造器和克隆方法。(代码如下) 编辑克隆对象后,还将编辑“原始”对象。 我做错了什么 我的自定义对象 public class FormData { HashMap<String, Object> values; String stgFormInstanceId, requestId, stgFormDatenTransfer; // Constructor for creating data with WebS

我用两种不同的策略“克隆”了一个对象。克隆构造器和克隆方法。(代码如下) 编辑克隆对象后,还将编辑“原始”对象。 我做错了什么

我的自定义对象

public class FormData {

    HashMap<String, Object> values; 
    String stgFormInstanceId, requestId, stgFormDatenTransfer;

    // Constructor for creating data with WebService
    public FormData(SoapObject so, StgForm form) {....}

    // Constructor for creating new data
    public FormData() {....}

    // clone Constructor
    public FormData(FormData oldData) {
        this.requestId = oldData.requestId;
        this.stgFormDatenTransfer = oldData.stgFormDatenTransfer;
        this.stgFormInstanceId = oldData.stgFormInstanceId;
        this.values = oldData.values;
        this.toString();
    }

    // Clone Method
    public FormData cloneFormData() {
        FormData newData = new FormData();
        newData.requestId = this.requestId;
        newData.stgFormDatenTransfer = this.stgFormDatenTransfer;
        newData.stgFormInstanceId = this.stgFormInstanceId;
        newData.values = this.values;
        newData.toString();
        return newData;
    }

    public void addValue(String key, Object value) {
        this.values.put(key, value);
    }
}
公共类FormData{
HashMap值;
字符串stgFormInstanceId、requestId、stgformDataTransfer;
//用于使用WebService创建数据的构造函数
public FormData(SoapObject so,StgForm form){..}
//用于创建新数据的构造函数
public FormData(){….}
//克隆构造函数
公共FormData(FormData oldData){
this.requestId=oldData.requestId;
this.stgformdatantransfer=oldData.stgformdatantransfer;
this.stgFormInstanceId=oldData.stgFormInstanceId;
this.values=oldData.values;
this.toString();
}
//克隆法
public FormData cloneFormData(){
FormData newData=新FormData();
newData.requestId=this.requestId;
newData.stgFormDatenTransfer=this.stgFormDatenTransfer;
newData.stgFormInstanceId=this.stgFormInstanceId;
newData.values=this.values;
newData.toString();
返回新数据;
}
public void addValue(字符串键、对象值){
this.values.put(键,值);
}
}
我的活动:

public class DetailActivity extends ActionBarActivity implements
        ActionBar.TabListener {

    private static HashMap<String, StgField> fields;
    private ActionBar actionBar;
    private FormData data;
    private FormData editedData;
    private String instanceId, requestId;
    private ViewPager viewPager;
    private TabsPagerAdapter mAdapter;
    private static ViewMode viewMode;
    private static ArrayList<EditText> editTextList;
    private StgForm currentForm;
    private Context context;
    private FormData editedData2;
    private FormData editedData3;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    ...
    data = ....;
    }

    private void editTicket() {
        setViewMode(ViewMode.edit);

        editedData2 = new FormData(data);
        editedData3 = data.cloneFormData();

        setEditabilityOfFields(fields, true);
        getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
    }

    private void saveTabValues(int position) {

        ArrayList<StgField> fields = getFieldsOfTAB(position);
        for (StgField field : fields) {
            View view = field.getViewItem();

            if (view instanceof EditText) {
                EditText et = (EditText) view;
                String fieldName=field.getFieldName();
                Editable value = et.getText();
                String s = value.toString();

                try {
                    editedData2.addValue(fieldName,
                            s);
                } catch (Exception e) {}
                try {
                    editedData3.addValue(fieldName,
                            s);
                } catch (Exception e) {}                
            }
        }
        System.out.println(data.toString());
        System.out.println("-------------");
        System.out.println(editedData2.toString());
        System.out.println("-------------");
        System.out.println(editedData3.toString());
    }
}
公共类DetailActivity扩展了ActionBarActivity实现
ActionBar.TabListener{
私有静态HashMap字段;
私人ActionBar ActionBar;
私有数据;
私有FormData编辑数据;
私有字符串instanceId,requestId;
私人视页机视页机;
私人TabsPagerAdapter mAdapter;
私有静态视图模式;
私有静态ArrayList editTextList;
私有StgForm当前表单;
私人语境;
私有表单数据编辑数据2;
私有表单数据编辑数据3;
@凌驾
创建时受保护的void(Bundle savedInstanceState){
...
数据=。。。。;
}
私人票证(){
setViewMode(ViewMode.edit);
editedData2=新表单数据(数据);
editedData3=data.cloneFormData();
setEditabilityOfFields(字段,true);
getWindow().setSoftInputMode(
WindowManager.LayoutParams.SOFT\u输入\u状态\u始终可见);
}
私有void saveTabValues(int位置){
ArrayList字段=getFieldsOfTAB(位置);
用于(标准字段:字段){
视图=field.getViewItem();
如果(查看EditText的实例){
EditText et=(EditText)视图;
字符串fieldName=field.getFieldName();
可编辑值=et.getText();
字符串s=value.toString();
试一试{
editedData2.addValue(字段名,
s) );
}捕获(例外e){}
试一试{
editedData3.addValue(字段名,
s) );
}捕获(例外e){}
}
}
System.out.println(data.toString());
System.out.println(“--------------”;
System.out.println(editeddata.toString());
System.out.println(“--------------”;
System.out.println(editeddata.toString());
}
}
现在,在我的活动中调用editTicket()和saveTABvalues()之后,所有三个对象 data/editData2/editData3是相同的。这对于editData2和editData3是可以的,但我不明白,为什么“数据”也改变了


感谢您的帮助

您正在从公共FormData(FormData oldData)中的“数据”传输数据;在editTicket()中;因此,无论何时编辑Edit2或Edit3,都会更改数据的原始值。您需要在克隆方法中使用clone(),或者在任何适用的情况下使用新对象(oldObject),比如String s=newstring(oldString)

编辑:

当我说“转移”时,我的意思是你只是给原始值分配了一个引用。因此,您没有在公共FormData(FormData oldData)中创建nw值

愚蠢的我。。。 我必须这么做

// clone Constructor
public FormData(FormData oldData) {
    requestId = new String(oldData.requestId.toString());
    stgFormDatenTransfer = new String (oldData.stgFormDatenTransfer.toString());
    values = new HashMap<String,Object>(oldData.values);        
}
//克隆构造函数
公共FormData(FormData oldData){
requestId=新字符串(oldData.requestId.toString());
stgFormDatenTransfer=新字符串(oldData.stgFormDatenTransfer.toString());
values=新的HashMap(oldData.values);
}

只是没有用=新字符串(…)创建新的属性

谢谢你的回复,但我不理解。在public FormData cloneFormData()中,我确实创建了一个新对象,用实际值填充它并返回它。公共FormData(FormData oldData)构造函数不是自己创建一个新对象吗?我的意思是,它是一个构造函数……这正是我写的:
[…]新对象(oldObject),只要适用,比如String s=newstring(oldString);[…]
。但我很高兴你明白了。