Java之函数值传递和对象传递

欢迎关注WX公众号:
门徒与思索

Java之函数值传递和对象传递

文章链接:http://blog.csdn.net/qq_16628781/article/details/72810012

知识点:

  1. 函数传参问题提出;
  2. 函数传参问题的总结;
  3. 实例讲解给函数传基本数据类型和对象;
  4. 新名词记录{Java函数传值和传递引用}

概览

在我们写函数的时候,我们经常需要传递参数进去,但是传参这里却是有个不太令人注意的大学问,如果不能好好理解,那么出现一些会令你“意想不到”的怪事。

未能正确的理解传参的问题,就会导致一些人为很奇怪的现象出现。例如,有次在项目中,传递了一个List类型的参数,但是很奇怪的是,每次执行那个方法之后,在函数外面的那个list对象被置空了。

那时候一直都没有想到是什么问题导致的。今天特意搜寻了下关于Java函数传参的问题,才理解了这个问题。

先来一个总结。

总结

Java的参数传递中,分为值传递和引用传递。(很多人说后面一个是对象传递,但是Java中,一切皆对象,还是说引用传递比较好),下面先来一个总结:

  1. 如果传递如果是基本数据类型传值,对形参的修改不会影响实参。
  2. 如果传递的是非基本数据类型,例如包装类型对象,那么形参和实参指向同一个内存地址(同一个对象),所以对形参的修改会影响到实参的属性。

解释1:基本的数据类型包括,byte,short,int,long,double,char,string以及他们的包装类型。他们是不可改变的数据类型了。

解释2:非基本数据类型包括,list,stringbuffer,以及自定义的实体类都属于非基本数据类型。

实例讲解

  1. 传递基本数据类型int
//ParamsPass类的方法
public void paramPassTest1(Integer a) {
       a = 20;
       System.out.println(TAG + ": " + a);
}
//调用上面的方法
ParamsPass paramsPass = new ParamsPass();
Integer a = new Integer(99);
paramsPass.paramPassTest1(a);
System.out.println(TAG + a);

执行上面的方法,看到传递的int类型实参在函数内部被调用了,外面的a的值没有改变。结果如下图所示:
Java之函数值传递和对象传递_第1张图片

  1. 传递对象

userbean实体类

public class UserBean implements Serializable {
   //串行化版本统一标识符
   private static final long serialVersionUID = 1L;
   
   private String password;

   public String getPassword() {
       return password;
   }

   public void setPassword(String password) {
       this.password = password;
   }
}
//1、测试方法
   public void paramPassTest2(UserBean userBean) {
       System.out.println("inside_func_userbean_hashcode: " + userBean.hashCode());
       userBean.setPassword("000000");
       System.out.println("inside_func_userbean_password: " + userBean.getPassword());
   }
   //2、调用测试方法
       ParamsPass paramsPass = new ParamsPass();
       UserBean userBean = new UserBean();
       userBean.setPassword("123456");
       System.out.println("outside_func_before_Password: " + userBean.getPassword());
       System.out.println("outside_func_before_hashcode: " + userBean.hashCode());
       paramsPass.paramPassTest2(userBean);
       System.out.println("outside_func_after_Password: " + userBean.getPassword());
       System.out.println("outside_func_after_hashcode: " + userBean.hashCode());

在上面中,传入了一个userbean实体类对象,初始设置的密码是“123456”,然后在里面,将密码改成“000000”;最后将在外面的userbean对象和传入到函数里面的对象的hashcode打印出来,结果居然是同一个地址,由此说明传递对象的是一个对象的引用,在方法里面进行修改对象的参数,会将引用的对象进行修改。
Java之函数值传递和对象传递_第2张图片

  1. 传入list对象
//userbean和上面的是一样的,这里省略了
//测试方法,打印hashcode和值
    public void paramPassTest3(List list) {
       System.out.println("inside_func_hashcode: " + list.hashCode());
       list.add("other value");
       System.out.println("inside_func_after_added_size: " + list.size());
       list.clear();
       System.out.println("inside_func_after_cleared_size: " + list.size());
   }
   //调用上面的测试方法
           List stringList = new ArrayList<>();
       stringList.add("value1");
       stringList.add("value2");
       System.out.println("outside_func_before_hashcode: " + stringList.hashCode());
       System.out.println("outside_func_before_size: " + stringList.size());
       paramsPass.paramPassTest3(stringList);
       System.out.println("outside_func_after_size: " + stringList.size());
       System.out.println("outside_func_after_hashcode: " + stringList.hashCode());

结果如下图所示:
Java之函数值传递和对象传递_第3张图片
可以看到打印输出,两个对象是同一个对象,所以传递list对象的时候,传递的也是对象的引用,对形参list对象进行操作,同时也会影响外面实参的属性。因为list已经不是一个基本的数据类型了。
同理的,stringbuffer,stringBuilder也是如此。

伪总结

说了这么多了,在开始提出的那个疑问,就得到解决了。这里就不再啰嗦了,总结在前面已经写了。

以上那个就是所有内容,如有任何问题,请及时与我联系,谢谢。

你可能感兴趣的:(Java)