Java中参数传递是值传递,还是引用传递的一次深究


 Java中参数传递是值传递,还是引用传递的一次深究

是我自己分析的,可能不准确,请大牛们指导,欢迎大家拍砖

1 先回顾一下java基础内容:对象在内存分配方式

public static void main(String[] args)
{
    Person p = new Person();
}


 这一句"Person p = new Person();" 分配了两个对象.
 一个是引用对象p分配在栈中,
 一个是实体对象new Person(),分配在堆上

并且p保存了实体对象的地址

 如下图所示

 栈内存                                                                                  堆内存

 引用对象p指向了 一个实体对象 Person.
  对于堆上和栈上分配内存的释放,有java基础的人都知道,在这里就不说了。不知道可以百度。
 

 2 函数中参数传递的两种类型 
   2.1  参数类型为基本类型  如 int float 等等
   基本类型传递举例

public class PersonDemo
{ 
 public static void main(String[] args)
 {
  int n =100;
  System.out.println(n);
  changeN(n);
  System.out.println(n);
 }
 
 public static int changeN(int a)
 {
  return a = a+1;
 }
}


相信大家都知道结果:
   100
   100
   从这里,我们都可以看出java中方法的参数传递是按值传递的。


   2.2   参数类型为对象类型 如Person
   例子一

public class PersonDemo
{
  public static void main(String[] args)
  {
   Person p = new Person();
   p.age = 10;
   System.out.println("传递前age=" +p.age);
   changeAge(p);
   System.out.println("传递后age=" +p.age);
  }
  public static int changeN(int a)
  {
   return a = a+1;
  }
  public static void changeAge(Person per)
  {
   per.age += 10;
  }
}

 class Person  
 {
  int age;
 }

 

输出结果:
 传递前age=10
 传递后age=20
 可能有人会想 例子一这里传递的是对象的引用。

例子二

public class PersonDemo
 {
  public static void main(String[] args)
  {
   Person p = new Person();
   p.age = 10;
   System.out.println("传递前age=" +p.age);
   changePerson(p);
   System.out.println("传递后age=" +p.age);
  } 
  public static int changeN(int a)
  {
   return a = a+1;
  }
  public static void changeAge(Person per)
  {
   per.age += 10;
  }  
  public static void changePerson(Person per)
  {
   Person p1 = new Person();
   p1.age = 50;
   per =p1;
  }
 }
 class Person  
 {
  int age;
 }



  输出结果
  传递前age=10
  传递后age=10 
  可能有人会想 例子二中这里传递的是对象的引用的一个复制。
  对于例子二我想了一个图示

对于第二种参数传入类型为对象的情况,解释有3种
  说法1 参数是按引用传递的,对于说法1 还有两种解释,
  解释1 引用传递时是传入对象的引用
  解释2 引用传递时是传入对象引用的复制
  说法2 参数是按值传递

  到底关于对象类型的参数,java中是按什么传递的,
  其实java中不管是对象参数还是基本类型参数,都是按值传递的。

我们可以对方法中参数某些值进行打印 比如 Hashcode
  这是部分代码 Person类可以参考上面定义的。
 

public class PersonDemo
 {
  
  public static void main(String[] args)
  {
   Person p = new Person();
   System.out.println("传递前hascode=" +p.hashCode());
   hc(p);
  }
  
  public static void hc(Person per)
  {
   System.out.println("传递后hascode=" +per.hashCode());
  }
 }


 

输出结果
 传递前hascode=29855319
    传递后hascode=29855319
 我们可以看出 参数中传递进来的对象的hashcode和参数外面的一样。
 我们再看一个例子

 public class PersonDemo
 {
  static Person CP = new Person();
  public static void main(String[] args)
  {
   equalPer(CP);
  }
  
  public static void equalPer(Person per)
  {
   System.out.println("比较对象结果:" +(per == CP));
  }
 }


输出结果
 比较对象结果:true
 用==进行比较, 我们一直都认为是比较的值相等,而不是内容。
 查看JDK文档中队 hashcode方法的描述,有这么一段话
   实际上,由 Object 类定义的 hashCode 方法确实会针对不同的对象返回不同的整数。
 这一般是通过将该对象的内部地址转换成一个整数来实现的,但是 JavaTM 编程语言不需要这种实现技巧。)
 通过上面的分析,关于对象传递,传递的是对象的一个引用(这里的引用跟c++中的引用不是一回事),这里的引用对象
 是"该对象的内部地址转换成一个整数" ,其实就是一个整数。
 所以我们可以肯定了java中不管是对象参数还是基本类型参数,都是按值传递的。 
 
 附带说明:
 c++里面关于对象的一些知识
  c++也是面向对象的语言,c++里面建立对象的方法是 :Person * p1 = new Person;
  new出来返回的是一个对象的指针,java中没有指针这个说法。
  而这个栈上的指针p也是指向堆上的new Person对象。
  貌似跟java很类似,的确很类似 如果你在c++中也实现类似的改变Person中age的方法

 public  void changeAge(Person * p)
  {
  p->age += 10;
  }

 他也改变 Person中age的值。他传入的是一个指针类型,从这个角度可以看出,C++中传递是按值传递的。


  C++中按引用传递的方式是这样的

  public  void changeAge(Person & p)
  {
  p.age += 10;
  }


 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值