Java外部变量作为参数传递到方法时,值发生变化问题

首先看一下这个问题。

Java值传递 or 引用传递?

这两个概念在用C写代码的时候很常见,但是Java到底是属于哪种呢?

值传递:通俗的讲就是将变量具体的值拿来传递给方法,也可以认为形参是实参的一个副本。

引用传递:传递的是变量的地址,操作形参相当于操作实参一样。

1、创建User对象,以及Activity和layout。

package com.phone.mine_module.bean;

import android.os.Parcel;
import android.os.Parcelable;

import androidx.annotation.NonNull;

public class User implements Parcelable, Cloneable {

    private String name;
    private String sex;
    private int age;

    public User(String name, String sex, int age) {
        this.name = name;
        this.sex = sex;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "User{" +
                "name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                ", age=" + age +
                '}';
    }

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(Parcel dest, int flags) {
        dest.writeString(this.name);
        dest.writeString(this.sex);
        dest.writeInt(this.age);
    }

    public void readFromParcel(Parcel source) {
        this.name = source.readString();
        this.sex = source.readString();
        this.age = source.readInt();
    }

    protected User(Parcel in) {
        this.name = in.readString();
        this.sex = in.readString();
        this.age = in.readInt();
    }

    public static final Parcelable.Creator<User> CREATOR = new Parcelable.Creator<User>() {
        @Override
        public User createFromParcel(Parcel source) {
            return new User(source);
        }

        @Override
        public User[] newArray(int size) {
            return new User[size];
        }
    };

    @NonNull
    @Override
    public Object clone() throws CloneNotSupportedException {
        return super.clone();
    }
}
package com.phone.mine_module.ui;

import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.appcompat.widget.Toolbar;

import com.phone.common_library.base.BaseAppActivity;
import com.phone.common_library.manager.LogManager;
import com.phone.mine_module.R;
import com.phone.mine_module.bean.User;

import java.util.ArrayList;
import java.util.List;

/**
 * 参数传递值改变问题
 */
public class ParamsTransferChangeProblemActivity extends BaseAppActivity {

    private static final String TAG = ParamsTransferChangeProblemActivity.class.getSimpleName();
    private Toolbar toolbar;
    private TextView tevTitle;
    private TextView tevUserBeforeChange;
    private TextView tevNumberBeforeChange;
    private TextView tevStrBeforeChange;
    private TextView tevStringListBeforeChange;
    private LinearLayout layoutAfterChange;
    private TextView tevUserAfterChange;
    private TextView tevNumberAfterChange;
    private TextView tevStrAfterChange;
    private TextView tevStringListAfterChange;
    private TextView tevUserAfterChange2;
    private TextView tevStringListAfterChange2;


    private User user;
    private int number;
    private String str;
    private ArrayList<String> stringList = new ArrayList<>();

    @Override
    protected int initLayoutId() {
        return R.layout.activity_params_transfer_change_problem;
    }

    @Override
    protected void initData() {
        user = new User("Erwin", "man", 25);
        number = 10;
        str = "Rommel";
        stringList.add("Manstein");
        stringList.add("Manstein2");
        stringList.add("Manstein3");
        stringList.add("Manstein4");
        stringList.add("Manstein5");
    }

    @Override
    protected void initViews() {
        toolbar = (Toolbar) findViewById(R.id.toolbar);
        tevTitle = (TextView) findViewById(R.id.tev_title);
        tevUserBeforeChange = (TextView) findViewById(R.id.tev_user_before_change);
        tevNumberBeforeChange = (TextView) findViewById(R.id.tev_number_before_change);
        tevStrBeforeChange = (TextView) findViewById(R.id.tev_str_before_change);
        tevStringListBeforeChange = (TextView) findViewById(R.id.tev_stringList_before_change);
        layoutAfterChange = (LinearLayout) findViewById(R.id.layout_after_change);
        tevUserAfterChange = (TextView) findViewById(R.id.tev_user_after_change);
        tevNumberAfterChange = (TextView) findViewById(R.id.tev_number_after_change);
        tevStrAfterChange = (TextView) findViewById(R.id.tev_str_after_change);
        tevStringListAfterChange = (TextView) findViewById(R.id.tev_stringList_after_change);
        tevUserAfterChange2 = (TextView) findViewById(R.id.tev_user_after_change2);
        tevStringListAfterChange2 = (TextView) findViewById(R.id.tev_stringList_after_change2);

        setToolbar(false, R.color.color_FFE066FF);

    }

    @Override
    protected void initLoadData() {
        LogManager.i(TAG, "change before user*****" + user);
        LogManager.i(TAG, "change before number*****" + number);
        LogManager.i(TAG, "change before str*****" + str);
        LogManager.i(TAG, "change before stringList*****" + stringList);
        tevUserBeforeChange.setText("before_change:" + user.toString());
        tevNumberBeforeChange.setText("before_change:" + String.valueOf(number));
        tevStrBeforeChange.setText("before_change:" + str);
        tevStringListBeforeChange.setText("before_change:" + stringList.toString());
//        change(user, number, str, stringList);
//        LogManager.i(TAG, "change after user*****" + user);
//        LogManager.i(TAG, "change after number*****" + number);
//        LogManager.i(TAG, "change after str*****" + str);
//        LogManager.i(TAG, "change after stringList*****" + stringList.toString());
//        tevUserAfterChange.setText("after_change:" + user.toString());
//        tevNumberAfterChange.setText("after_change:" + String.valueOf(number));
//        tevStrAfterChange.setText("after_change:" + str);
//        tevStringListAfterChange.setText("after_change:" + stringList.toString());
        layoutAfterChange.setVisibility(View.GONE);


        try {
            change2((User) user.clone(), (ArrayList<String>) stringList.clone());
            LogManager.i(TAG, "change2 after user*****" + user);
            LogManager.i(TAG, "change2 after stringList*****" + stringList.toString());
            tevUserAfterChange2.setText("before_change2:" + user.toString());
            tevStringListAfterChange2.setText("before_change2:" + stringList.toString());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }

    private void change(User user, int number, String str, final List<String> stringList) {
        user.setAge(26);
        user.setName("Erwin2");
        number = 11;
        str = "Rommel2";
        stringList.add("Manstein6");
    }

    private void change2(final User user, final ArrayList<String> stringList) {
        user.setAge(27);
        user.setName("Erwin3");
        stringList.add("Manstein7");
    }


}

public abstract class BaseAppActivity extends AppCompatActivity {
	
	protected BaseApplication          baseApplication;
//	protected QMUILoadingView          loadView;
//	protected FrameLayout.LayoutParams layoutParams;
	protected Intent                   intent;
	protected Bundle                   bundle;
	protected AppCompatActivity        appCompatActivity;
	
	@Override
	protected void onCreate(@Nullable Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		
		appCompatActivity = this;
		baseApplication = (BaseApplication) getApplication();
		ActivityPageManager.getInstance().addActivity(appCompatActivity);
		
		setContentView(initLayoutId());
		ButterKnife.bind(appCompatActivity);
		
//		loadView = new QMUILoadingView(appCompatActivity);
//		loadView.setVisibility(View.GONE);
//		loadView.setSize(100);
//		loadView.setColor(getResources().getColor(R.color.color_80000000));
//		layoutParams = new FrameLayout.LayoutParams(
//			FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT);
//		layoutParams.gravity = Gravity.CENTER;
		
		//        setToolbar();
		initData();
		initViews();
		initLoadData();
	}
	
	@Override
	public void onConfigurationChanged(Configuration newConfig) {
		//非默认值
		if (newConfig.fontScale != 1) {
			getResources();
		}
		super.onConfigurationChanged(newConfig);
	}
	
	@Override
	public Resources getResources() {//还原字体大小
		Resources res = super.getResources();
		//非默认值
		if (res.getConfiguration().fontScale != 1) {
			Configuration newConfig = new Configuration();
			newConfig.setToDefaults();//设置默认
			res.updateConfiguration(newConfig, res.getDisplayMetrics());
		}
		return res;
	}
	
	protected abstract int initLayoutId();
	
	protected void setToolbar(boolean isDarkFont) {
		if (isDarkFont) {
			ImmersionBar.with(appCompatActivity) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(R.color.color_FFFFFFFF)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.keyboardEnable(true)
				.init();
		} else {
			ImmersionBar.with(appCompatActivity)
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(R.color.color_FF198CFF)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.keyboardEnable(true)
				.init();
		}
		
		ToolbarManager.assistActivity(findViewById(android.R.id.content));
	}
	
	protected void setToolbar(boolean isDarkFont, boolean isResizeChildOfContent) {
		if (isDarkFont) {
			ImmersionBar.with(appCompatActivity) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(R.color.color_FFFFFFFF)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.keyboardEnable(true)
				.init();
		} else {
			ImmersionBar.with(appCompatActivity)
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(R.color.color_FF198CFF)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.keyboardEnable(true)
				.init();
		}
		
		if (isResizeChildOfContent) {
			ToolbarManager.assistActivity(findViewById(android.R.id.content));
		}
	}
	
	protected void setToolbar(boolean isDarkFont, int color) {
		if (isDarkFont) {
			ImmersionBar.with(appCompatActivity) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(color)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.init();
		} else {
			ImmersionBar.with(appCompatActivity)
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(color)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.init();
		}
		
		ToolbarManager.assistActivity(findViewById(android.R.id.content));
	}
	
	protected void setToolbar(boolean isDarkFont, int color, boolean isResizeChildOfContent) {
		if (isDarkFont) {
			ImmersionBar.with(appCompatActivity) //原理:如果当前设备支持状态栏字体变色,会设置状态栏字体为黑色,如果当前设备不支持状态栏字体变色,会使当前状态栏加上透明度,否则不执行透明度
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(color)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.init();
		} else {
			ImmersionBar.with(appCompatActivity)
				.statusBarDarkFont(isDarkFont)
				.statusBarColor(color)     //状态栏颜色,不写默认透明色
				//                    .autoStatusBarDarkModeEnable(true, 0.2f) //自动状态栏字体变色,必须指定状态栏颜色才可以自动变色哦
				.init();
		}
		
		if (isResizeChildOfContent) {
			ToolbarManager.assistActivity(findViewById(android.R.id.content));
		}
	}
	
	/**
	 * 初始化沉浸式
	 * Init immersion bar.
	 */
	protected void initImmersionBar() {
		//设置共同沉浸式样式
		ImmersionBar.with(appCompatActivity).navigationBarColor(R.color.color_FFE066FF).init();
	}
	
	protected abstract void initData();
	
	protected abstract void initViews();
	
	protected abstract void initLoadData();
	
	protected void showToast(String message, boolean isLongToast) {
		//        Toast.makeText(appCompatActivity, message, Toast.LENGTH_LONG).show();
		if (!appCompatActivity.isFinishing()) {
			Toast toast;
			int duration;
			if (isLongToast) {
				duration = Toast.LENGTH_LONG;
			} else {
				duration = Toast.LENGTH_SHORT;
			}
			toast = Toast.makeText(appCompatActivity, message, duration);
			toast.setGravity(Gravity.CENTER, 0, 0);
			toast.show();
		}
	}
	
	protected void showCustomToast(int left, int right,
		int textSize, int textColor,
		int bgColor, int height,
		int roundRadius, String message) {
		FrameLayout frameLayout = new FrameLayout(appCompatActivity);
		FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, FrameLayout.LayoutParams.WRAP_CONTENT);
		frameLayout.setLayoutParams(layoutParams);
		TextView textView = new TextView(appCompatActivity);
		FrameLayout.LayoutParams layoutParams1 = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.WRAP_CONTENT, height);
		textView.setLayoutParams(layoutParams1);
		textView.setPadding(left, 0, right, 0);
		textView.setTextSize(textSize);
		textView.setTextColor(textColor);
		textView.setGravity(Gravity.CENTER);
		textView.setIncludeFontPadding(false);
		GradientDrawable gradientDrawable = new GradientDrawable();//创建drawable
		gradientDrawable.setColor(bgColor);
		gradientDrawable.setCornerRadius(roundRadius);
		textView.setBackground(gradientDrawable);
		textView.setText(message);
		frameLayout.addView(textView);
		
		Toast toast = new Toast(appCompatActivity);
		toast.setView(frameLayout);
		toast.setDuration(Toast.LENGTH_LONG);
		toast.show();
	}
	
	public boolean isOnMainThread() {
		return Looper.getMainLooper().getThread().getId() == Thread.currentThread().getId();
	}
	
	protected void startActivity(Class<?> cls) {
		intent = new Intent(appCompatActivity, cls);
		startActivity(intent);
	}
	
	protected void startActivityCarryParams(Class<?> cls, Map<String, String> params) {
		intent = new Intent(appCompatActivity, cls);
		bundle = new Bundle();
		
		if (params != null && params.size() > 0) {
			for (String key : params.keySet()) {
				if (params.get(key) != null) {//如果参数不是null,才把参数传给后台
					bundle.putString(key, params.get(key));
				}
			}
			intent.putExtras(bundle);
		}
		startActivity(intent);
	}
	
	protected void startActivityForResult(Class<?> cls, int requestCode) {
		intent = new Intent(appCompatActivity, cls);
		startActivityForResult(intent, requestCode);
	}
	
	protected void startActivityForResultCarryParams(Class<?> cls, Map<String, String> params, int requestCode) {
		intent = new Intent(appCompatActivity, cls);
		bundle = new Bundle();
		
		if (params != null && params.size() > 0) {
			for (String key : params.keySet()) {
				if (params.get(key) != null) {//如果参数不是null,才把参数传给后台
					bundle.putString(key, params.get(key));
				}
			}
			intent.putExtras(bundle);
		}
		startActivityForResult(intent, requestCode);
	}
	
	protected boolean isEmpty(String dataStr) {
		if (dataStr != null && !"".equals(dataStr)) {
			return false;
		} else {
			return true;
		}
	}
	
	@Override
	protected void onDestroy() {
		ActivityPageManager.getInstance().removeActivity(appCompatActivity);
		super.onDestroy();
	}
}

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".ui.ParamsTransferChangeProblemActivity">

    <androidx.core.widget.NestedScrollView
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        tools:ignore="ScrollViewCount">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="vertical">

            <androidx.appcompat.widget.Toolbar
                android:id="@+id/toolbar"
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_75"
                android:background="@color/color_FFE066FF"
                android:minHeight="?attr/actionBarSize"
                android:orientation="vertical"
                app:contentInsetStart="0dp">

                <TextView
                    android:id="@+id/tev_title"
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_50"
                    android:layout_marginTop="@dimen/dp_25"
                    android:gravity="center"
                    android:text="@string/params_transfer_change_problem"
                    android:textColor="@color/color_FF198CFF"
                    android:textSize="@dimen/sp_20" />

            </androidx.appcompat.widget.Toolbar>

            <TextView
                android:id="@+id/tev_user_before_change"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="before_change:user"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

            <TextView
                android:id="@+id/tev_number_before_change"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="before_change:number"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

            <TextView
                android:id="@+id/tev_str_before_change"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="before_change:str"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

            <TextView
                android:id="@+id/tev_stringList_before_change"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="before_change:stringList"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

            <LinearLayout
                android:id="@+id/layout_after_change"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="vertical">

                <View
                    android:layout_width="match_parent"
                    android:layout_height="@dimen/dp_50" />

                <TextView
                    android:id="@+id/tev_user_after_change"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@color/color_FFFFC73B"
                    android:gravity="start|center_vertical"
                    android:includeFontPadding="false"
                    android:paddingStart="@dimen/dp_17"
                    android:paddingTop="@dimen/dp_17"
                    android:paddingEnd="@dimen/dp_17"
                    android:paddingBottom="@dimen/dp_17"
                    android:text="after_change:user"
                    android:textColor="@color/color_FFFFFFFF"
                    android:textSize="@dimen/sp_16" />

                <TextView
                    android:id="@+id/tev_number_after_change"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@color/color_FFFFC73B"
                    android:gravity="start|center_vertical"
                    android:includeFontPadding="false"
                    android:paddingStart="@dimen/dp_17"
                    android:paddingTop="@dimen/dp_17"
                    android:paddingEnd="@dimen/dp_17"
                    android:paddingBottom="@dimen/dp_17"
                    android:text="after_change:number"
                    android:textColor="@color/color_FFFFFFFF"
                    android:textSize="@dimen/sp_16" />

                <TextView
                    android:id="@+id/tev_str_after_change"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@color/color_FFFFC73B"
                    android:gravity="start|center_vertical"
                    android:includeFontPadding="false"
                    android:paddingStart="@dimen/dp_17"
                    android:paddingTop="@dimen/dp_17"
                    android:paddingEnd="@dimen/dp_17"
                    android:paddingBottom="@dimen/dp_17"
                    android:text="after_change:str"
                    android:textColor="@color/color_FFFFFFFF"
                    android:textSize="@dimen/sp_16" />

                <TextView
                    android:id="@+id/tev_stringList_after_change"
                    android:layout_width="match_parent"
                    android:layout_height="wrap_content"
                    android:layout_gravity="center"
                    android:background="@color/color_FFFFC73B"
                    android:gravity="start|center_vertical"
                    android:includeFontPadding="false"
                    android:paddingStart="@dimen/dp_17"
                    android:paddingTop="@dimen/dp_17"
                    android:paddingEnd="@dimen/dp_17"
                    android:paddingBottom="@dimen/dp_17"
                    android:text="after_change;stringList"
                    android:textColor="@color/color_FFFFFFFF"
                    android:textSize="@dimen/sp_16" />

            </LinearLayout>

            <View
                android:layout_width="match_parent"
                android:layout_height="@dimen/dp_50" />

            <TextView
                android:id="@+id/tev_user_after_change2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="after_change:user"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

            <TextView
                android:id="@+id/tev_stringList_after_change2"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_gravity="center"
                android:background="@color/color_FFFFC73B"
                android:gravity="start|center_vertical"
                android:includeFontPadding="false"
                android:paddingStart="@dimen/dp_17"
                android:paddingTop="@dimen/dp_17"
                android:paddingEnd="@dimen/dp_17"
                android:paddingBottom="@dimen/dp_17"
                android:text="after_change;stringList"
                android:textColor="@color/color_FFFFFFFF"
                android:textSize="@dimen/sp_16" />

        </LinearLayout>

    </androidx.core.widget.NestedScrollView>

</LinearLayout>

2、运行一下,可以看到结果。

下面是相关场景的测试用例:

    @Override
    protected void initLoadData() {
        LogManager.i(TAG, "change before user*****" + user);
        LogManager.i(TAG, "change before number*****" + number);
        LogManager.i(TAG, "change before str*****" + str);
        LogManager.i(TAG, "change before stringList*****" + stringList);
        tevUserBeforeChange.setText("before_change:" + user.toString());
        tevNumberBeforeChange.setText("before_change:" + String.valueOf(number));
        tevStrBeforeChange.setText("before_change:" + str);
        tevStringListBeforeChange.setText("before_change:" + stringList.toString());
        change(user, number, str, stringList);
        LogManager.i(TAG, "change after user*****" + user);
        LogManager.i(TAG, "change after number*****" + number);
        LogManager.i(TAG, "change after str*****" + str);
        LogManager.i(TAG, "change after stringList*****" + stringList.toString());
        tevUserAfterChange.setText("after_change:" + user.toString());
        tevNumberAfterChange.setText("after_change:" + String.valueOf(number));
        tevStrAfterChange.setText("after_change:" + str);
        tevStringListAfterChange.setText("after_change:" + stringList.toString());

    }


    private void change(User user, int number, String str, final List<String> stringList) {
        user.setAge(26);
        user.setName("Erwin2");
        number = 11;
        str = "Rommel2";
        stringList.add("Manstein6");
    }

可以看到,int和String这种变量作为参数传到方法内部之后改变其值(调用change方法后),外部变量(原变量)不会发生变化;User和List<String>这种变量作为参数传到方法内部之后改变其值,外部变量(原变量)会发生变化,其中User的属性发生了变化(比如:name由Erwin变成了Erwin2,age由Erwin变成了Erwin2),List<String>的size也发生了变化(由size=5变成了size=6)。

如果说对象用的是引用传递,那么在change方法中重新new了一个新的对象(值还是原来的),然后修改新对象的值,主方法中打印出来的对象属性应该和change方法中的一致。

但是,上面明明也可以修改原对象的值,这又是为什么?

可以这么认为,在传递参数的时候,是用原对象的副本(指向实际的地址)来传递,在函数中是可以执行修改对应实际地址中的值,所以主方法中会同样感知到修改。

但是如果将方法中的参数指向新的地址,比如new 一个新的对象或者将别的对象重新赋值给参数,这样形参和实参指向的就不是同一个地址空间,任何修改都不会引起原对象的变化。

3、clone(),具体clone的内容这里不作分析,主要看看最上面问题所反映的现象。

下面是相关场景的测试用例:


    @Override
    protected void initLoadData() {
        LogManager.i(TAG, "change before user*****" + user);
        LogManager.i(TAG, "change before number*****" + number);
        LogManager.i(TAG, "change before str*****" + str);
        LogManager.i(TAG, "change before stringList*****" + stringList);
        tevUserBeforeChange.setText("before_change:" + user.toString());
        tevNumberBeforeChange.setText("before_change:" + String.valueOf(number));
        tevStrBeforeChange.setText("before_change:" + str);
        tevStringListBeforeChange.setText("before_change:" + stringList.toString());
//        change(user, number, str, stringList);
//        LogManager.i(TAG, "change after user*****" + user);
//        LogManager.i(TAG, "change after number*****" + number);
//        LogManager.i(TAG, "change after str*****" + str);
//        LogManager.i(TAG, "change after stringList*****" + stringList.toString());
//        tevUserAfterChange.setText("after_change:" + user.toString());
//        tevNumberAfterChange.setText("after_change:" + String.valueOf(number));
//        tevStrAfterChange.setText("after_change:" + str);
//        tevStringListAfterChange.setText("after_change:" + stringList.toString());
        layoutAfterChange.setVisibility(View.GONE);


        try {
            change2((User) user.clone(), (ArrayList<String>) stringList.clone());
            LogManager.i(TAG, "change2 after user*****" + user);
            LogManager.i(TAG, "change2 after stringList*****" + stringList.toString());
            tevUserAfterChange2.setText("before_change2:" + user.toString());
            tevStringListAfterChange2.setText("before_change2:" + stringList.toString());
        } catch (CloneNotSupportedException e) {
            e.printStackTrace();
        }

    }


    private void change2(final User user, final ArrayList<String> stringList) {
        user.setAge(27);
        user.setName("Erwin3");
        stringList.add("Manstein7");
    }

​​​​​​​

因此,可以看到,(User) user.clone()和(ArrayList<String>) stringList.clone()这种变量作为参数传到方法内部之后改变其值,外部变量(原变量)不会发生变化。

最后总结

我们常见的User user = new User(); User user2; user=user2; 这种形式的代码复制的是引用,即对象在内存中的地址,user和user2对象仍然指向了同一个对象。而通过clone方法赋值的对象跟原来的对象是同时独立存在的。

如对此有疑问,请联系qq1164688204。

推荐Android开源项目

项目功能介绍:RxJava2和Retrofit2项目,添加自动管理token功能,添加RxJava2生命周期管理,使用App架构设计是MVP模式和MVVM模式,同时使用组件化,部分代码使用Kotlin,此项目持续维护中。

项目地址:https://gitee.com/urasaki/RxJava2AndRetrofit2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值