首先看一下这个问题。
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
|