Java中参数传递问题总结


1.问题说明

       在C++中,函数调用时有传值调用和传址调用两种方式,但在Java中只有传值调用一种方式。Java中的方法参数为那几种基本数据类型的情况跟C++中一样,传入的只是变量的拷贝。而当参数类型为类对象时,则有可能会误以为是传址调用。


   在Java的方法调用中,方法中的参数是以传值的形式进行的,不管它是什么数据类型。如果是基本数据类型,则就是传入该值的一个拷贝;如果是类类型,则传入的是引用的一个拷贝。归根结底还是传的值。

2.基本数据类型作为形参

(1)非数组型基本数据类型作为形参
        int a=1;
        change(a);
        System.out.println(a);           //1
	public static void change(int a1){
		a1=10;
	}

该种传递实质上传入的是a的一个copy,赋给了形式参数a1,a1的值初始等于a,但无论怎么改变形式参数a1的值,都不会改变实际参数的值。

(2)基本数据类型以数组名形式作为形参
	int[] b={1,2,3,4};
	change(b);
	System.out.println(b[0]);         //10
	public static void change(int[] b1){
             b1[0]=10;
             b1=new int[]{0,9,8};
       }

首先了解数组在内存中是如何分配空间的。
int [ ] b={1,2,3,4}; 
①首先在栈中分配四个int 类型的空间,首地址赋给变量b,可通过b[0]、b[1]、b[2]、b[3]访问数组中数据
②其次,change(b),传进去的实际上是b的地址,即数组的首地址,形式参数b1作为b的一个copy,和b都指向同一个块内存,即数组首地址,所以改变b1[0]、b1[1]等等,就等同于改变该内存中的数据,故形参对该块内存的改变等效于通过实参对该数组的改变。
但是,
b1=new int[]{0,9,8};
b1新分配一个数组空间,此时,对原内存中数组数据是没有影响的,b1指向其他内存,b仍然指向原内存,故不会对实参b造成影响。

3. 引用类型作为形式参数(普通类对象作为形式参数)
change(p);
public static void change(Point2D p1){
	p1=new Point2D(32,43);
}
public static void hange(Point2D p1){
	p2.setX(35);
	
}

以上两种调用方式最常见。

由于引用类型传递实质是对传入变量p的一个copy,所以形式参数p2和实际参数p指向同一块内存,同一个对象,故通过形式参数p2对 对象内部数据的改变,就是改变了实际参数指向对象的内部数据,因为是同一块内存。
但通过
p1=new Point2D(32,43);
这种新创建对象的方式,p1指向新的内存,新的对象,故其操作与实际参数p再无关系,不会使实际参数p指向的对象造成改变。

4. String类型作为形式参数
(1)非数组型的String类作为形式参数
String类比较特殊,虽然它也是引用类型,但是存储方式不完全等同于其他引用类型。涉及到String类在内存中存储知识敬请点击这 点击打开链接

	String s=new String("hello");
	change(s);
	System.out.println(s);               //hello
        public static void change(String str){
        str="world";
        
    }
String s=new String("hello")在内存中的实现:

 


<span style="font-size:18px;">change(s);</span>     
public static void change(String str){
        str="world";

在内存中形式参数的变化:


故非数组型String类作为形式参数时,形式参数的改变不会影响实际参数的值。

(2)数组型String类作为形式参数


		
	String[] s2={"abc","cde","edf"};
	System.out.println(s2[0]);
	change(s2);
	System.out.println(s2[0]);
      public static void change(String[] s1) {
        s1[0]="world";
        
    }

此原理和数组型基本数据类型作为形参相似。

5.StringBuffer(StringBuilder类作为形参)
StringBuffer类和String类不同,String类的对象中的字符串不能改变,但StringBuffer类对象的字符串可以添加、修改
	
      StringBuffer sb=new StringBuffer(s1);
      StringBuffer sb2=new StringBuffer(s2);
      System.out.println(sb+"---"+s2);//hello---world
      change(sb,sb2);
      System.out.println(sb+"---"+s2); // world---worldworld

          public static void change(String s1, String s2) {
		
		s1=s2;   //s1=="world",s1指向s2的缓冲区
               s2=s1+s2;// s2="worldworld",s1="worldworld",因为s1和s2指向同一块缓冲区
		System.out.println(s1);
		System.out.println(s2);
		System.out.println("-----------");
	}






  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值