【问题标题】:java/android: editing an object after clone/duplicate also edits the originaljava/android:在克隆/复制后编辑对象也会编辑​​原始对象
【发布时间】:2014-09-08 14:58:18
【问题描述】:

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

我的自定义对象

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);
    }
}

我的活动:

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());
    }
}

现在,在我的 Activity 中调用 editTicket() 和 saveTABvalues() 之后,所有三个对象 data / editData2 / editData3 是一样的。这对editData2和editData3来说没问题,但我不明白,为什么“数据”也发生了变化……

感谢您的帮助

【问题讨论】:

    标签: java android clone


    【解决方案1】:

    您正在从公共 FormData(FormData oldData) 中的“数据”中传输数据;在编辑票();因此,每当您编辑 Edit2 或 Edit3 时,您也会更改数据的原始值。您需要在您的克隆方法中使用 clone(),或者在适用时使用 new Object(oldObject),例如 String s = new String(oldString);

    编辑:

    当我说“转移”时,我的意思是您只是在分配对原始值的引用。所以你没有在你的 public FormData(FormData oldData) 中创建一个 nw 值;

    【讨论】:

    • 感谢您的回复,但我不明白。在公共 FormData cloneFormData() 中,我确实创建了一个新对象,用实际值填充它并返回它。 public FormData(FormData oldData) 构造函数不是自己创建一个新对象吗?我的意思是,它是一个构造函数...
    【解决方案2】:

    愚蠢的我... 我必须这样做

    // 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);        
    }
    

    只是没有使用 = new String(...);

    创建 new 属性

    【讨论】:

    • 这正是我写的:[...] new Object(oldObject) whenever applicable, like String s = new String(oldString);[...]。但我很高兴你明白了。
    猜你喜欢
    • 2015-01-23
    • 2017-07-20
    • 1970-01-01
    • 2016-01-10
    • 2011-12-30
    • 2017-12-16
    • 2013-04-06
    • 2013-01-03
    • 2016-02-21
    相关资源
    最近更新 更多